C# 和 Java DES 加密值不相同

2022-01-10 00:00:00 encryption cryptography c# java

我正在尝试使用 C# 和 Java 加密相同的数据.如果数据超过 7 个字节,则 Java 和 C# 的加密值不相同.

I am trying to encrypt the same data using C# and Java. If the data is more than 7 bytes then Java and C#'s encrypted value are not identical.

  • 输入1:a
    java 输出:FrOzOp/2Io8=
    C# 输出:FrOzOp/2Io8=

输入 2:abc
j : H9A/ahl8K7I=
c#: H9A/ahl8K7I=

输入 3:aaaaaaaa(问题)
j : Gxl7e0aWPd7j6l7uIEuMxA==
c#:Gxl7e0aWPd7sf1xR6hK4VQ==

这里是C#和Java方法的实现.
C#代码:

Here is the implementation of C# and Java methods.
C# code:

public String saltTxt = "12345678";
public String Encrypt(String txt)
{
        byte[] data = Encrypt(Encoding.UTF8.GetBytes(txt));
        
        DESCryptoServiceProvider alg = new DESCryptoServiceProvider();

        alg.Key = Encoding.UTF8.GetBytes(saltTxt.ToCharArray(), 0, cprovider.KeySize / 8);
        alg.IV = new byte[8];

        MemoryStream ms = new MemoryStream();
        CryptoStream stem = new CryptoStream( ms, cprovider.CreateEncryptor(),CryptoStreamMode.Write);

        stem.Write(txt, 0, txt.Length);
        stem.FlushFinalBlock();

        data = ms.ToArray();
        
        return Convert.ToBase64String(data);
 }

Java 代码:

public String saltTxt = "12345678";
public String Encrypt(String str) {
    try {
        KeySpec myKey = new DESKeySpec(saltTxt.getBytes("UTF8"));
        SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(myKey);
        Cipher ecipher = Cipher.getInstance("DES");
        ecipher.init(Cipher.ENCRYPT_MODE, key);

        byte[] data = str.getBytes("UTF8");

        byte[] crypt = ecipher.doFinal(data);
        
        return new BASE64Encoder().encode(crypt);
    } catch (Exception ex) {
    }

    return null;
} 

知道为什么它没有按预期工作吗?

Any idea why it's not working as expected?

推荐答案

问题出在模式的加密.

SunJCE 提供程序使用 ECB 作为默认模式,PKCS5Padding 作为 DES 的默认填充方案,DES-EDE 和 Blowfish 密码.(JCA 文档)

SunJCE provider uses ECB as the default mode, and PKCS5Padding as the default padding scheme for DES, DES-EDE and Blowfish ciphers. (JCA Doc)

.Net中,对称算法的默认操作模式是CipherMode.CBC,默认填充是PaddingMode.PKCS7.(msdn..SymmetricAlgorithm)

In .Net, The default operation mode for the symmetric algorithm is CipherMode.CBC and default padding is PaddingMode.PKCS7. (msdn..SymmetricAlgorithm)

以下更改解决了该问题.

The following changes resolve the problem.

// in C# 
DESCryptoServiceProvider alg = new DESCryptoServiceProvider();
alg.Mode = CipherMode.ECB;  // specified 

// in java
chiper = Cipher.getInstance("DES/CBC/PKCS5Padding");

两边不要改变.

相关文章