为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

qq_花开花谢_0 2022-10-26 15:55:29
我正在尝试将现有的 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”
查看完整描述

2 回答

?
喵喔喔

TA贡献1735条经验 获得超5个赞

密文不同,因为PasswordDeriveBytes在 C# 代码和PBKDF2WithHmacSHA1Java 代码中生成不同的密钥:

除了 C#-type 之外PasswordDeriveBytes,还有 C#-type Rfc2898DeriveBytes,它是 PBKDF2 的实现,带有 SHA-1,因此PBKDF2WithHmacSHA1与 Java 代码中的对应。

如果可能,Rfc2898DeriveBytes应该在 C# 代码中使用 代替PasswordDeriveBytes,例如参见此处此处的PBKDF2部分。然后两个代码返回相同的密文。

据我所知,没有提供 C#-type 的 Java 实现的提供程序PasswordDeriveBytes。但是,Internet 上有功能相同的 Java 实现,例如这里。如果 Java 代码使用这样的实现而不是PBKDF2WithHmacSHA1,则两个代码都返回相同的密文。但正如已经提到的,这应该是第二选择。


查看完整回答
反对 回复 2022-10-26
?
烙印99

TA贡献1829条经验 获得超13个赞

正如下面所承诺的那样是解决方案 - 再次感谢您的支持


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;

    }

}


查看完整回答
反对 回复 2022-10-26
  • 2 回答
  • 0 关注
  • 150 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号