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 也是如此。