无法在.net中使用Java加密的TripleDES解密

本文关键字:加密 Java TripleDES 解密 net | 更新日期: 2023-09-27 18:18:14

我们有一个Java客户端,它向我们发送一些加密数据1. 随机字符串使用RSA和我们离线提供的公钥进行加密。2. 使用步骤1中生成的密钥加密数据,使用alg_tripleDES_CBC = http://www.w3.org/2001/04/xmlenc#tripledes-cbc

我能够像这样从第一步解密密钥…

public static string DecryptKey(string encryptedKey)
    {
        X509Certificate2 cert = new X509Certificate2("c:''test.pfx", "test");
        RSACryptoServiceProvider privateKeyProvider = (RSACryptoServiceProvider)cert.PrivateKey;
        string decryptedKey = System.Text.Encoding.UTF8.GetString(privateKeyProvider.Decrypt(Convert.FromBase64String(encryptedKey), false));
        return decryptedKey;
    }

我有这个代码来使用第一步生成的密钥解密数据。

 public static string DecryptString(string Message, string Passphrase)
    {
        byte[] Results;
        System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
        MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
        byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));
        TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();
        TDESAlgorithm.Key = TDESKey;
        TDESAlgorithm.Mode = CipherMode.ECB;
        TDESAlgorithm.Padding = PaddingMode.PKCS7;
        byte[] DataToDecrypt = Convert.FromBase64String(Message);
        try
        {
            ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor();
            Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length);
        }
        finally
        {
            TDESAlgorithm.Clear();
            HashProvider.Clear();
        }
        return UTF8.GetString(Results);
    }

第二步因为这个异常而失败。

   System.Security.Cryptography.CryptographicException: Bad Data.
   at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
   at System.Security.Cryptography.Utils._DecryptData(SafeKeyHandle hKey, Byte[] data, Int32 ib, Int32 cb, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode PaddingMode, Boolean fDone)
   at System.Security.Cryptography.CryptoAPITransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
   at ConsoleApplication3.Program.DecryptString(String Message, String Passphrase) in C:'Documents and Settings'rjaladi'Desktop'ConsoleApplication3'ConsoleApplication3'Program.cs:line 66
   at ConsoleApplication3.Program.Main(String[] args) in C:'Documents and Settings'rjaladi'Desktop'ConsoleApplication3'ConsoleApplication3'Program.cs:line 22 

我需要和我们的客户确认什么?我知道我们传递给TDES的参数有问题。任何帮助吗?

编辑:相应的Java代码加密消息。

public String encryptText(String plainText) throws Exception{
  byte[] plaintext = plainText.getBytes();
  byte[] tdesKeyData = key;
  byte[] myIV = initializationVector;
  Cipher c3des = Cipher.getInstance(""DESede/CBC/NoPadding"");
  SecretKeySpec    myKey = new SecretKeySpec(tdesKeyData, "DESede");
  IvParameterSpec ivspec = new IvParameterSpec(myIV);
     c3des.init(Cipher.ENCRYPT_MODE, myKey, ivspec);
  byte[] cipherText = c3des.doFinal(plaintext);
  sun.misc.BASE64Encoder obj64=new sun.misc.BASE64Encoder();
  return obj64.encode(cipherText);
 }

无法在.net中使用Java加密的TripleDES解密

这可能会失败:

TDESAlgorithm.Mode = CipherMode.ECB;

如果您使用CBC加密Java,则应该使用CBC密码模式。不建议使用ECB,因为它有一些安全漏洞。

你的异常被抛出在_DecryptData(...),我注意到包括一个PaddingMode参数。将检查最后一个块末尾的填充,如果发现不正确的填充则抛出错误。我建议你检查谁是发送数据,看看他们正在使用什么填充模式。您需要在解密时使用相同的填充模式。

正如@klartrex所说,你不应该使用ECB模式,它会泄露信息;请看这里的(字面)插图。如果你能说服另一端这样做,请使用CBC或CTR模式。