需要帮助将 C# 加密方法转换为 Java

我正在尝试将现有的 C# 加密方法转换为 Java,但遇到了如下障碍


例如,当我用 c# 加密一个基本字符串“12345”时,我得到这个输出 8ZQZEURctqP1PMmQxVtCcA==


当我用 java 加密相同的字符串时,我得到了这个 jkEZp2cfeGXVE/IxIW6X3g==


private static string Encrypt(string plainText, string passPhrase, string saltValue, string hashAlgorithm, int passwordIterations,

                        string initVector, int keySize)

{

    try

    {

        byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);

        byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);

        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

        PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm, passwordIterations);

        byte[] keyBytes = password.GetBytes(keySize / 8);

        RijndaelManaged symmetricKey = new RijndaelManaged { Mode = CipherMode.CBC };

        ICryptoTransform encryptor = symmetricKey.CreateEncryptor(keyBytes, initVectorBytes);

        MemoryStream memoryStream = new MemoryStream();

        CryptoStream cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write);

        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);

        cryptoStream.FlushFinalBlock();

        byte[] cipherTextBytes = memoryStream.ToArray();

        memoryStream.Close();

        cryptoStream.Close();

        string cipherText = Convert.ToBase64String(cipherTextBytes);

        return cipherText;

    }

    catch (Exception execp)

    {

        MessageBox.Show(string.Format("Exception in Encrypt function\r\nError: {0}", execp.Message));

        return "";

    }

}


下面是我转换为 java 的内容,但仍然没有得到相同的加密输入和输出 - 我只是将“ProtectPassword”重命名为“Encrypt”,将“UnprotectPassword”重命名为“Decrypt”


qq_花开花谢_0
浏览 151回答 2
2回答

喵喔喔

密文不同,因为PasswordDeriveBytes在 C# 代码和PBKDF2WithHmacSHA1Java 代码中生成不同的密钥:PBKDF2WithHmacSHA1顾名思义,它是使用 SHA-1的 PBKDF 2的实现。的实现PasswordDeriveBytes基于 PBKDF 1,但增加了一些扩展。除了 C#-type 之外PasswordDeriveBytes,还有 C#-type Rfc2898DeriveBytes,它是 PBKDF2 的实现,带有 SHA-1,因此PBKDF2WithHmacSHA1与 Java 代码中的对应。如果可能,Rfc2898DeriveBytes应该在 C# 代码中使用 代替PasswordDeriveBytes,例如参见此处或此处的PBKDF2部分。然后两个代码返回相同的密文。据我所知,没有提供 C#-type 的 Java 实现的提供程序PasswordDeriveBytes。但是,Internet 上有功能相同的 Java 实现,例如这里。如果 Java 代码使用这样的实现而不是PBKDF2WithHmacSHA1,则两个代码都返回相同的密文。但正如已经提到的,这应该是第二选择。

烙印99

正如下面所承诺的那样是解决方案 - 再次感谢您的支持public static class Encryption{    public static string Encrypt(string text)    {        var thePassword = "%cFRm*F)N9Rq[6#5";        byte[] IV = Encoding.UTF8.GetBytes("7!,V5u]Bu>q>7zY'");        var md5 = new MD5CryptoServiceProvider();        var password = md5.ComputeHash(Encoding.ASCII.GetBytes(thePassword));        var cipher = new RijndaelManaged();                    var encryptor = cipher.CreateEncryptor(password, IV);        var buffer = Encoding.ASCII.GetBytes(text);        return Convert.ToBase64String(encryptor.TransformFinalBlock(buffer, 0, buffer.Length));    }    public static string Decrypt(string text)    {        var thePassword = "%cFRm*F)N9Rq[6#5";        byte[] IV = Encoding.UTF8.GetBytes("7!,V5u]Bu>q>7zY'");        var md5 = new MD5CryptoServiceProvider();        var password = md5.ComputeHash(Encoding.ASCII.GetBytes(thePassword));        var cipher = new RijndaelManaged();        var decryptor = cipher.CreateDecryptor(password, IV);        byte[] input = Convert.FromBase64String(text);        var newClearData = decryptor.TransformFinalBlock(input, 0, input.Length);        return Encoding.ASCII.GetString(newClearData);    }}和java等价物public class Encryption {    public static String Encrypt(String str)    {        try         {            String thePassword = "%cFRm*F)N9Rq[6#5";            byte[] encryptedData;            byte[] IV = "7!,V5u]Bu>q>7zY'".getBytes();            MessageDigest digest = MessageDigest.getInstance("MD5");                        SecretKeySpec password = new SecretKeySpec(digest.digest(thePassword.getBytes()), "AES");            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");            IvParameterSpec IVParamSpec = new IvParameterSpec(IV);            cipher.init(Cipher.ENCRYPT_MODE, password, IVParamSpec);            encryptedData = cipher.doFinal(str.getBytes());            return DatatypeConverter.printBase64Binary(encryptedData);        } catch (Exception e) {            e.printStackTrace();        }        return null;    }       public static String Decrypt(String str)    {        try         {            String thePassword = "%cFRm*F)N9Rq[6#5";            byte[] encryptedData = DatatypeConverter.parseBase64Binary(str);             byte[] IV = "7!,V5u]Bu>q>7zY'".getBytes();            MessageDigest digest = MessageDigest.getInstance("MD5");                        SecretKeySpec password = new SecretKeySpec(digest.digest(thePassword.getBytes()), "AES");            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");            IvParameterSpec IVParamSpec = new IvParameterSpec(IV);            cipher.init(Cipher.DECRYPT_MODE, password, IVParamSpec);            byte[] decryptedVal = cipher.doFinal(encryptedData);            return new String(decryptedVal);         } catch (Exception e) {            e.printStackTrace();        }        return null;    }}
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java