0

我们正在我们的应用程序中实现某种自动登录,并在 C# 中解密一些在 java 中加密的东西时感到震惊。

基本上,Java 应用程序会生成某种 URL。当用户点击链接时,我需要验证查询字符串,如果匹配,让用户登录。

有人提供了java代码。我需要将相同的代码转换为 C#,因为我的应用程序是 C#。当我在 C# 中完全实现它时出现错误。

这是java解密代码:

String vParameter= "ksyR31QsRcbeJoysNOsAGBHajLKWsT00wavt9LJYGOMRC8zc_vqrNOeOlGHKJHIt3sLmFhDVw_JZKr4JT0H3Jj7_Di9bKNw99qCzMOKCXYM=";  //The string that nees to be decoded.
byte[] encryptedV = Base64.decodeBase64(vParameter);
String salt = “jkjkyt4”; // the i parameter - user’s id
String password = “^hjkh673!v@!a89mz+%5rT”; // application specific
MessageDigest digester = MessageDigest.getInstance("SHA-1");
digester.update((salt + password).getBytes("UTF-8"));
byte[] key = digester.digest();
SecretKeySpec secretKey = new SecretKeySpec(key, 2, 16, “AES”);
String appIV = "SampleIV"// application specific
IvParameterSpec iv= new IvParameterSpec(appIV.getBytes(“UTF-8”));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
byte[] decryptedV = cipher.doFinal(encryptedV, 0, encryptedV.length);
String v = new String(decryptedV, “UTF-8”);

这是对应的C#代码

        string vParameter = "ksyR31QsRcbeJoysNOsAGBHajLKWsT00wavt9LJYGOMRC8zc_vqrNOeOlGHKJHIt3sLmFhDVw_JZKr4JT0H3Jj7_Di9bKNw99qCzMOKCXYM="; //v parameter
        byte[] encryptedV = Encoding.UTF8.GetBytes(vParameter);
        String salt = "jkjkyt4"; // the i parameter - user’s id
        String password = "^hjkh673!v@!a89mz+%5rT"; // application specific
        var sha1 = SHA1Managed.Create();

        byte[] keyBytes = Encoding.UTF8.GetBytes(salt + password); //salt + password
        byte[] key = sha1.ComputeHash(keyBytes);
        byte[] finalKey = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 };
        String appIV = "SampleIV";
        byte[] iv = Encoding.UTF8.GetBytes(appIV); //iv
        Array.Copy(key, 2, finalKey, 0, 16); //key 2, 16
        AesManaged tdes = new AesManaged();
        tdes.Key = finalKey;
        tdes.Mode = CipherMode.CBC;
        tdes.Padding = PaddingMode.PKCS7;
        tdes.IV = iv;
        ICryptoTransform crypt = tdes.CreateDecryptor();
        byte[] cipher = crypt.TransformFinalBlock(encryptedV, 0, encryptedV.Length);
        string decryptedText = Convert.ToBase64String(cipher);
        return decryptedText;

我究竟做错了什么?谁能指出错误?

编辑:我已经更新了 V 参数...注意 - 密钥、密码和 IV 不是真实的。我不得不更改它们,因为我不希望我的公司密钥公开。

编辑 2:嗨,我已经更新了 vParameter.. 现在它们是一样的。Java 代码正在运行......它已在另一个应用程序中实现。现在,我必须为我的 C# 应用程序创建一个类似的版本。你们能指出 C# 代码中的任何问题吗?

4

1 回答 1

3

您正在混淆 UTF8 编码/解码和 base64 编码/解码。此外,发布的代码也不起作用,因为密文和 IV 的长度错误。我怀疑这只是因为您更改了它们以避免泄露您的真实数据。

无论如何,这是一个返回相同结果的 Java 片段和 C# 片段:

Java(我只将 vParameter 和 appIV 更改为有效的东西):

String vParameter= "Lq4aURUiyvKvEZBWMWpUr2wRSMu96E+J1UeHLTOhKEM=";  //The string that needs to be decoded.
byte[] encryptedV = Base64.decodeBase64(vParameter.getBytes("ASCII"));
String salt = "jkjkyt4"; // the i parameter - user’s id
String password = "^hjkh673!v@!a89mz+%5rT"; // application specific
MessageDigest digester = MessageDigest.getInstance("SHA-1");
digester.update((salt + password).getBytes("UTF-8"));
byte[] key = digester.digest();
SecretKeySpec secretKey = new SecretKeySpec(key, 2, 16, "AES");
String appIV = "SampleIV12345678";// application specific
IvParameterSpec iv= new IvParameterSpec(appIV.getBytes("UTF-8"));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
byte[] decryptedV = cipher.doFinal(encryptedV, 0, encryptedV.length);
String v = new String(decryptedV, "UTF-8");
System.out.println(v); // foobarfoobarfoobarfoobarfoobar

C#(使用 Base64 解码 vParameter 并将解密的数据解码为 UTF-8。还将 AES 对象重命名为 aes 而不是 tdes。):

string vParameter = "Lq4aURUiyvKvEZBWMWpUr2wRSMu96E+J1UeHLTOhKEM="; //v parameter
byte[] encryptedV = Convert.FromBase64String(vParameter);
string salt = "jkjkyt4"; // the i parameter - user’s id
string password = "^hjkh673!v@!a89mz+%5rT"; // application specific
var sha1 = SHA1Managed.Create();
byte[] keyBytes = Encoding.UTF8.GetBytes(salt + password); //salt + password
byte[] key = sha1.ComputeHash(keyBytes);
byte[] finalKey = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 };
string appIV = "SampleIV12345678";
byte[] iv = Encoding.UTF8.GetBytes(appIV); //iv
Array.Copy(key, 2, finalKey, 0, 16); //key 2, 16
AesManaged aes = new AesManaged();
aes.Key = finalKey;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.IV = iv;
ICryptoTransform crypt = aes.CreateDecryptor();
byte[] cipher = crypt.TransformFinalBlock(encryptedV, 0, encryptedV.Length);
string decryptedText = Encoding.UTF8.GetString(cipher);
Console.WriteLine(decryptedText); // foobarfoobarfoobarfoobarfoobar
于 2012-12-18T12:44:13.653 回答