iOS 和 C# 之间的 AES 加密
AES Encryption between iOS and C#
我正在使用 FBEncryptor 库进行加密和解密。如果我从 iOS 加密数据,它会在 C# 服务器端轻松解密。但是在解密原始数据的前 10 个字符时会损坏。
示例:
从 C# 接收数据:0Nwr30kSkJxGCYiFg8TUrfW51587SUkS8lQ7Uno7gglxjVGW5gR4MA+isTknjXzK
用于加密的密钥:e64f9fa01f0418
来自 iOS 的解密数据:gZUUTabcdefghijklmnopqrstuvwxyz"}
预期解密数据:{"Successeed":"abcdefghijklmnopqrstuvwxyz"}
iOS 边码:
encryptedios = "0Nwr30kSkJxGCYiFg8TUrfW51587SUkS8lQ7Uno7gglxjVGW5gR4MA+isTknjXzK"
let decryptedString = FBEncryptorAES.decryptBase64String(encryptedios , keyString: "e64f9fa01f0418")
C#代码:
public RijndaelManaged GetRijndaelManaged(String secretKey)
{
var keyBytes = new byte[16];
var secretKeyBytes = Encoding.UTF8.GetBytes(secretKey);
Array.Copy(secretKeyBytes, keyBytes, Math.Min(keyBytes.Length, secretKeyBytes.Length));
return new RijndaelManaged
{
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7,
KeySize = 128,
BlockSize = 128,
Key = keyBytes,
IV = keyBytes
};
}
public byte[] Encrypt(byte[] plainBytes, RijndaelManaged rijndaelManaged)
{
return rijndaelManaged.CreateEncryptor()
.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
}
public byte[] Decrypt(byte[] encryptedData, RijndaelManaged rijndaelManaged)
{
return rijndaelManaged.CreateDecryptor()
.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
}
/// <summary>
/// Encrypts plaintext using AES 128bit key and a Chain Block Cipher and returns a base64 encoded string
/// </summary>
/// <param name="plainText">Plain text to encrypt</param>
/// <param name="key">Secret key</param>
/// <returns>Base64 encoded string</returns>
public String Encrypt(String plainText, String key)
{
var plainBytes = Encoding.UTF8.GetBytes(plainText);
return Convert.ToBase64String(Encrypt(plainBytes, GetRijndaelManaged(key)));
}
/// <summary>
/// Decrypts a base64 encoded string using the given key (AES 128bit key and a Chain Block Cipher)
/// </summary>
/// <param name="encryptedText">Base64 Encoded String</param>
/// <param name="key">Secret Key</param>
/// <returns>Decrypted String</returns>
public String Decrypt(String encryptedText, String key)
{
var encryptedBytes = Convert.FromBase64String(encryptedText);
return Encoding.UTF8.GetString(Decrypt(encryptedBytes, GetRijndaelManaged(key)));
}
您的第一个块不同,因为您在解密中使用了不同的 IV。在 IOS decryptBase64String(..)
中不要将 IV 作为输入,这会触发它被初始化为全 0。在 C# 中,您将其初始化为与 key 相同的值。
一般而言,IV 需要是在加密时生成的随机值,并与加密数据一起传递。通常它是在加密数据的前面,所以当你初始化你的解密库时你可以很容易地得到它。使用全 0 作为 IV 是不好的做法.. 将密钥用作 IV 也是如此。
我正在使用 FBEncryptor 库进行加密和解密。如果我从 iOS 加密数据,它会在 C# 服务器端轻松解密。但是在解密原始数据的前 10 个字符时会损坏。
示例:
从 C# 接收数据:0Nwr30kSkJxGCYiFg8TUrfW51587SUkS8lQ7Uno7gglxjVGW5gR4MA+isTknjXzK
用于加密的密钥:e64f9fa01f0418
来自 iOS 的解密数据:gZUUTabcdefghijklmnopqrstuvwxyz"}
预期解密数据:{"Successeed":"abcdefghijklmnopqrstuvwxyz"}
iOS 边码:
encryptedios = "0Nwr30kSkJxGCYiFg8TUrfW51587SUkS8lQ7Uno7gglxjVGW5gR4MA+isTknjXzK"
let decryptedString = FBEncryptorAES.decryptBase64String(encryptedios , keyString: "e64f9fa01f0418")
C#代码:
public RijndaelManaged GetRijndaelManaged(String secretKey)
{
var keyBytes = new byte[16];
var secretKeyBytes = Encoding.UTF8.GetBytes(secretKey);
Array.Copy(secretKeyBytes, keyBytes, Math.Min(keyBytes.Length, secretKeyBytes.Length));
return new RijndaelManaged
{
Mode = CipherMode.CBC,
Padding = PaddingMode.PKCS7,
KeySize = 128,
BlockSize = 128,
Key = keyBytes,
IV = keyBytes
};
}
public byte[] Encrypt(byte[] plainBytes, RijndaelManaged rijndaelManaged)
{
return rijndaelManaged.CreateEncryptor()
.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
}
public byte[] Decrypt(byte[] encryptedData, RijndaelManaged rijndaelManaged)
{
return rijndaelManaged.CreateDecryptor()
.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
}
/// <summary>
/// Encrypts plaintext using AES 128bit key and a Chain Block Cipher and returns a base64 encoded string
/// </summary>
/// <param name="plainText">Plain text to encrypt</param>
/// <param name="key">Secret key</param>
/// <returns>Base64 encoded string</returns>
public String Encrypt(String plainText, String key)
{
var plainBytes = Encoding.UTF8.GetBytes(plainText);
return Convert.ToBase64String(Encrypt(plainBytes, GetRijndaelManaged(key)));
}
/// <summary>
/// Decrypts a base64 encoded string using the given key (AES 128bit key and a Chain Block Cipher)
/// </summary>
/// <param name="encryptedText">Base64 Encoded String</param>
/// <param name="key">Secret Key</param>
/// <returns>Decrypted String</returns>
public String Decrypt(String encryptedText, String key)
{
var encryptedBytes = Convert.FromBase64String(encryptedText);
return Encoding.UTF8.GetString(Decrypt(encryptedBytes, GetRijndaelManaged(key)));
}
您的第一个块不同,因为您在解密中使用了不同的 IV。在 IOS decryptBase64String(..)
中不要将 IV 作为输入,这会触发它被初始化为全 0。在 C# 中,您将其初始化为与 key 相同的值。
一般而言,IV 需要是在加密时生成的随机值,并与加密数据一起传递。通常它是在加密数据的前面,所以当你初始化你的解密库时你可以很容易地得到它。使用全 0 作为 IV 是不好的做法.. 将密钥用作 IV 也是如此。