我想在iOS应用程序中使用SymmetricKey和CryptoKit加密数据,并在Net Core中使用C#在服务器端解密。
iOS代码:
class Security {
static let keyStr = "d5a423f64b607ea7c65b311d855dc48f" //32
static let iv="31348c0987c7" //12
class func encode(_ text:String)->String {
let key=SymmetricKey(data: Security.keyStr.data(using: .utf8)!)
let nonce=try! AES.GCM.Nonce(data: iv.data(using: .utf8)!)
let encrypted=try! AES.GCM.seal(text.data(using: .utf8)!, using: key, nonce: nonce)
return encrypted.combined!.base64EncodedString()
}
}
我将加密结果传递到后端,然后进行解密
C#代码:
public string decrypt(string encryptedText)
{
string keyStr = "d5a423f64b607ea7c65b311d855dc48f";
string iv = "31348c0987c7";
string plaintext = "";
Debug.WriteLine(encryptedText);
using (Aes aesAlg = Aes.Create())
{
Debug.WriteLine(AesGcm.IsSupported);
var key = System.Text.Encoding.UTF8.GetBytes(keyStr);
var iV = System.Text.Encoding.UTF8.GetBytes(iv);
aesAlg.Key = key;
aesAlg.IV = iV;
// Create a decryptor to perform the stream transform.
ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
// Create the streams used for decryption.
using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(request.pswd)))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// Read the decrypted bytes from the decrypting stream
// and place them in a string.
plaintext = srDecrypt.ReadToEnd();
}
}
}
}
Debug.WriteLine(plaintext);
}
例如:测试加密为:金属氮 MOXy 氮 MOXy 氧氯化物氮 MOXy 氮 MOXy 氮 MOXy 氧氯化物氮 MOXy 氧氯化物氧氯化物氧氯化物=
当我到线:
aesAlg.IV = iV;
我得到一个错误“指定的初始化向量(IV)不匹配此算法的块大小”。看起来C#需要字节[16],但在iOS中我似乎坚持使用12。
我在这一点上卡住了。任何想法都非常感谢。谢谢。
1条答案
按热度按时间6ju8rftf1#
发布的Swift代码在GCM模式下应用AES,s.
AES.GCM
。发布的C#代码也使用AES,但不是GCM模式,而是默认的CBC模式(s.Aes
,Mode
)。CBC模式使用16字节的IV,而GCM模式使用12字节的nonce,这就是错误消息所指向的。
要成功解密,C#端也必须使用GCM模式的AES。在.NET中,
AesGcm
类支持GCM模式的AES(从.NET Core 3.0开始)。还应注意,Swift代码给出的数据是12字节随机数、密文和16字节标签(按此顺序)的级联的Base64编码,这些数据必须在C#代码中分离,其中各部分被单独处理。
一个可能的C#实现,用于解密由发布的Swift代码生成的密文,如下所示:
编辑:C#/BouncyCastle是本机.NET类
AesGcm
的一种替代方法。您的环境可能支持这种方法:注意,与原生的
AesGcm
类不同,C#/BouncyCastle需要将密文和标记连接在一起,因此只需要分离nonce。