【问题标题】:Result of Triple DES encryption in .Net and Java are different.Net 和 Java 中的三重 DES 加密结果不同
【发布时间】:2016-12-10 04:51:12
【问题描述】:

我正在尝试在 Java 和 .Net 中加密字符串。但问题是两种算法都会产生不同的结果。我正在使用三重 DES 加密算法。 它应该产生相同的结果。

我的 .Net 方法:

Public Function EncryptTripleDES(ByVal sIn As String, ByVal sKey As String) As String
    Dim DES As New System.Security.Cryptography.TripleDESCryptoServiceProvider
    Dim hashMD5 As New System.Security.Cryptography.MD5CryptoServiceProvider
    ' scramble the key
            ' Compute the MD5 hash.
    DES.Key = hashMD5.ComputeHash(System.Text.ASCIIEncoding.ASCII.GetBytes(sKey))
    ' Set the cipher mode.
    DES.Mode = System.Security.Cryptography.CipherMode.ECB
    ' Create the encryptor.
    Dim DESEncrypt As System.Security.Cryptography.ICryptoTransform = DES.CreateEncryptor()
    ' Get a byte array of the string.
    Dim Buffer As Byte() = System.Text.ASCIIEncoding.ASCII.GetBytes(sIn)
    ' Transform and return the string.
    Return Convert.ToBase64String(DESEncrypt.TransformFinalBlock(Buffer, 0, Buffer.Length))
End Function

我的 Java 类:

public class TrippleDESEncryption {
   private static final String UNICODE_FORMAT = "UTF8";
   public static final String DESEDE_ENCRYPTION_SCHEME = "DESede";
   private KeySpec keySpec;
   private SecretKeyFactory secretKeyFactory;
   private Cipher cipher;
   byte[] keyAsBytes;
   private String encryptionKey;
   private String encryptionScheme;
   SecretKey key;

   public TrippleDESEncryption() throws Exception {
          encryptionKey = "234342343423434234342343";
          encryptionScheme = DESEDE_ENCRYPTION_SCHEME;
          keyAsBytes = encryptionKey.getBytes(UNICODE_FORMAT);
          keySpec = new DESedeKeySpec(keyAsBytes);
          secretKeyFactory = SecretKeyFactory.getInstance(encryptionScheme);
          cipher = Cipher.getInstance(encryptionScheme);
          key = secretKeyFactory.generateSecret(keySpec);

   }

   /**
   * Method To Encrypt The String
   */
   public String encrypt(String unencryptedString) {
          String encryptedString = null;
          try {
                 cipher.init(Cipher.ENCRYPT_MODE, key);
                 byte[] plainText = unencryptedString.getBytes(UNICODE_FORMAT);
                 byte[] encryptedText = cipher.doFinal(plainText);
                 BASE64Encoder base64encoder = new BASE64Encoder();
                 encryptedString = base64encoder.encode(encryptedText);
          } catch (Exception e) {
                 e.printStackTrace();
          }
          return encryptedString;
    }
}

【问题讨论】:

  • 您发布了一个 java 类与一个 C# 方法,因此我们无法告诉您将正确的参数传递给 C# 方法。您正在使用 C# 中的 ASCII 和 Java 中的 UTF-8 来获取看起来错误的关键字节。我将首先检查这些 GetBytes 调用的结果。
  • 现在不要使用三重 DES。 即使您使用 192 位的最大密钥大小,它也最多只能提供 112 位的安全性。如果使用较短的密钥大小,则它仅提供 56 或 57 位的安全性。 AES 会更快(处理器具有特殊的 AES-NI 指令集),并且使用 128 位的最低密钥大小甚至更安全。 3DES 的最大密文大小也有实际限制。见Security comparison of 3DES and AES
  • 切勿使用ECB mode。它是确定性的,因此在语义上不安全。您至少应该使用像CBCCTR 这样的随机模式。最好对您的密文进行身份验证,以免像padding oracle attack 这样的攻击是不可能的。这可以通过 GCM 或 EAX 等认证模式或encrypt-then-MAC 方案来完成。
  • 一般建议:始终使用完全限定的密码字符串。 Cipher.getInstance("DESede"); 可能会产生不同的密码,具体取决于默认的安全提供程序。它最有可能导致"DESede/ECB/PKCS5Padding",但并非必须如此。如果它发生变化,您将失去不同 JVM 之间的兼容性。

标签: java .net vb.net encryption


【解决方案1】:

感谢大家的支持。我找到了解决方案,这是我的解决方案。这个 VB.NET 方法运行良好。我唯一的错误是我的 VB.NET 方法使用的是 ANSIEncoding 而 Java 类使用的是 UTF8。

 Public Function DecryptTripleDES(ByVal sOut As String, ByVal sKey As String) As String
    Try
        Dim DES As New System.Security.Cryptography.TripleDESCryptoServiceProvider
        DES.Key = UTF8Encoding.UTF8.GetBytes(sKey)
        ' Set the cipher mode.
        DES.Mode = System.Security.Cryptography.CipherMode.ECB
        ' Create the decryptor.
        Dim DESDecrypt As System.Security.Cryptography.ICryptoTransform = DES.CreateDecryptor()
        Dim Buffer As Byte() = Convert.FromBase64String(sOut)
        ' Transform and return the string.
        Return System.Text.UTF8Encoding.UTF8.GetString(DESDecrypt.TransformFinalBlock(Buffer, 0, Buffer.Length))
    Catch ex As Exception
        Throw New Exception()
    End Try
End Function

【讨论】:

  • 好的,如果你只对加密感兴趣而不对安全感兴趣。如果您需要安全性,请不要使用 3DES,因为它不安全,请使用 AES,不要使用 ECB 模式,因为它不安全,请使用带有随机 iv 的 CBC。请参阅 Artjom B 的 cmets。不要使用 ECB 模式,它不安全,请参阅 ECB mode,向下滚动到 Penguin。
  • 非常感谢@zaph 的宝贵意见。将来我会照顾它。我的问题是加密逻辑是由我的客户端(Java)决定的,我必须编写其等效的解密逻辑。
  • 又一个安全性不佳的案例,原因很糟糕,显然我们不是专业人士。
猜你喜欢
  • 1970-01-01
  • 2012-05-06
  • 1970-01-01
  • 2011-10-22
  • 2011-08-28
  • 2017-08-25
  • 1970-01-01
  • 2012-03-30
  • 1970-01-01
相关资源
最近更新 更多