AES加密/解密从c#到java

本文关键字:java 解密 加密 AES | 更新日期: 2023-09-27 18:07:52

我在应用程序中使用AES加密/解密算法。

在服务器端,我使用c#对数据进行加密/解密。

在客户端(android)我使用java来解密数据

c#加密/解密代码

    static readonly string PasswordHash = "52";
    static readonly string SaltKey = "dfkjsadfinewdfadsfkmeoinmsdflksdflk";
    static readonly string VIKey = "@EUBRHDFBFG8867";
public static string Encrypt(string plainText)
    {
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);
        byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash,Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
        var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding =PaddingMode.Zeros };
        var encryptor = symmetricKey.CreateEncryptor(keyBytes,Encoding.ASCII.GetBytes(VIKey));
        byte[] cipherTextBytes;
        using (var memoryStream = new MemoryStream())
        {
            using (var cryptoStream = new CryptoStream(memoryStream, encryptor,CryptoStreamMode.Write))
            {
                cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                cryptoStream.FlushFinalBlock();
                cipherTextBytes = memoryStream.ToArray();
                cryptoStream.Close();
            }
            memoryStream.Close();
        }           
       return Convert.ToBase64String(cipherTextBytes);
    }
    public static string Decrypt(string encryptedText)
    {
        byte[] cipherTextBytes = Convert.FromBase64String(encryptedText);
        byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash,Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);
        var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding =PaddingMode.None }
        var decryptor = symmetricKey.CreateDecryptor(keyBytes,Encoding.ASCII.GetBytes(VIKey));
        var memoryStream = new MemoryStream(cipherTextBytes);
        var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);
        byte[] plainTextBytes = new byte[cipherTextBytes.Length];
        int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);
        memoryStream.Close();
        cryptoStream.Close();
        return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount).TrimEnd("'0".ToCharArray());
    }

Java解密方法

public String decrypt(String dataToDecrypt) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, UnsupportedEncodingException 
{
    byte[] encryptedCombinedBytes = Base64.decodeBase64(dataToDecrypt.getBytes());
    String saltKey = "dfkjsadfinewdfadsfkmeoinmsdflksdflk";
    String password = "52";
    String IVKey = "@EUBRHDFBFG8867";
    PBKDF2Parameters p = new PBKDF2Parameters("HmacSHA256", "ASCII", saltKey.getBytes(), 8);
    byte[] mEncryptedPassword = new PBKDF2Engine(p).deriveKey(password);

    byte[] ivbytes = Arrays.copyOfRange(IVKey.getBytes(), 0, 16);
    SecretKeySpec mSecretKeySpec = new SecretKeySpec(mEncryptedPassword, "AES");
    Cipher mCipher = Cipher.getInstance("AES/CBC/NoPadding");
    mCipher.init(Cipher.DECRYPT_MODE, mSecretKeySpec, new IvParameterSpec(ivbytes));
    byte[] encryptedTextBytes = Arrays.copyOfRange(encryptedCombinedBytes, 16, encryptedCombinedBytes.length);
    byte[] decryptedTextBytes = mCipher.doFinal(encryptedTextBytes);
    return new String(decryptedTextBytes, "UTF-8");
}

c#解密方法工作良好,并给出结果字符串。

我无法找出Java解密代码中的问题。它运行并给我一些垃圾值。

编辑

    我不能在服务器端编辑任何东西。我只需要在java解密中复制解密。
  1. 我不知道如何使用passwordHash, saltKey和IVkey

AES加密/解密从c#到java

首先,你把密码和盐调换了。

其次,PBKDF2默认使用HMAC/SHA-1。据我所知,这也是Rfc2898DeriveBytes的默认值:

通过使用基于HMACSHA1的伪随机数生成器实现基于密码的密钥派生功能,PBKDF2。

你也不应该在Java中没有指定字符集的情况下调用getBytes,但这可能不是你当前运行时的问题。


这些只是对代码的注释;不使用CBC网络连接没有完整性/真实性保护