繁体   English   中英

Java DES 加密,C# DES 解密

[英]Java DES encrypt, C# DES decrypt

我收到了来自Java的加密字符串,我可以看到Java加密的源代码。 我用 C# 编写了解密代码。 但是总是在“FlushFinalBlock”处报错。 错误消息:“System.Security.Cryptography.CryptographicException。附加信息:数据不正确。”

任何人都可以指出问题出在我的 C# 代码中吗?

这是java代码:

private static byte[] coderByDES(byte[] plainText, String key, int mode)
            throws InvalidKeyException, InvalidKeySpecException,
            NoSuchAlgorithmException, NoSuchPaddingException,
            BadPaddingException, IllegalBlockSizeException,
            UnsupportedEncodingException {
        SecureRandom sr = new SecureRandom();
        byte[] resultKey = makeKey(key);
        DESKeySpec desSpec = new DESKeySpec(resultKey);
        SecretKey secretKey = SecretKeyFactory.getInstance("DES").generateSecret(desSpec);
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(mode, secretKey, sr);
        return cipher.doFinal(plainText);
    }

private static byte[] makeKey(String key)
            throws UnsupportedEncodingException {
        byte[] keyByte = new byte[8];
        byte[] keyResult = key.getBytes("UTF-8");
        for (int i = 0; i < keyResult.length && i < keyByte.length; i++) {
            keyByte[i] = keyResult[i];
        }
        return keyByte;
    }


private static String byteArr2HexStr(byte[] arrB) {
        int iLen = arrB.length;

        StringBuilder sb = new StringBuilder(iLen * 2);
        for (int i = 0; i < iLen; i++) {
            int intTmp = arrB[i];

            while (intTmp < 0) {
                intTmp = intTmp + 256;
            }

            if (intTmp < 16) {
                sb.append("0");
            }
            sb.append(Integer.toString(intTmp, 16));
        }
        return sb.toString();
    }

这是 C# 代码:

public static string DecryptForDES(string input, string key)
    {
        byte[] inputByteArray = HexStr2ByteArr(input);
        byte[] buffArray = null;
        using (DESCryptoServiceProvider des = new DESCryptoServiceProvider())
        {
            des.Key =  Encoding.UTF8.GetBytes(key); 
            des.IV =  Encoding.UTF8.GetBytes(key); 
            des.Mode = System.Security.Cryptography.CipherMode.ECB;
            des.Padding = PaddingMode.PKCS7;
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            using (CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write))
            {
                cs.Write(inputByteArray, 0, inputByteArray.Length);
                cs.FlushFinalBlock();//
                cs.Close();
            }
            buffArray = ms.ToArray();

            ms.Close();    
        }

        string str = string.Empty;
        if (buffArray != null)
        {
            str = Encoding.UTF8.GetString(buffArray);
        }
        return str;
    }



public static byte[] HexStr2ByteArr(string strIn)
    {
        byte[] arrB = Encoding.UTF8.GetBytes(strIn);
        int iLen = arrB.Length;

        byte[] arrOut = new byte[iLen / 2];
        byte[] arrTmp = new byte[2];
        for (int i = 0; i < iLen; i = i + 2)
        {
            string strTmp = Encoding.UTF8.GetString(arrB, i, 2);
            arrOut[i / 2] = (byte)Convert.ToInt32(strTmp, 16);
        }
        return arrOut;
    }

如果密码匹配,Java 加密部分和 C# 解密部分都可以在我的机器上运行。 否则抛出 System.Security.Cryptography.CryptographicException: ' Bad Data'。 在 C# 方法 DecryptForDES 中获取密码匹配替换

 des.Key = Encoding.UTF8.GetBytes(key); 

 des.Key = MakeKey(key);

使用 C# 方法:

 private static byte[] MakeKey(String key)
 {
     byte[] keyByte = new byte[8];
     byte[] keyResult = Encoding.UTF8.GetBytes(key); 
     for (int i = 0; i<keyResult.Length && i<keyByte.Length; i++) {
         keyByte[i] = keyResult[i];
     }
     return keyByte;
 }

对应于 Java 方法 makeKey(String key)。 此外,在 C# 方法中删除 DecryptForDES

 des.IV = Encoding.UTF8.GetBytes(key);

因为 ECB 模式不使用 IV。

在下面的测试用例中

 coderByDES("This is a plain text that needs to be encrypted...", "This is the key used for encryption...", Cipher.ENCRYPT_MODE);

返回字节数组

 a47b1b2c90fb3b7a0ab1f51f328ff55aae3c1eb7789c31c28346696a8b1f27c7413c14e68fe977d3235b5a6f63c07d7a95d912ff22f17ad6

 DecryptForDES("a47b1b2c90fb3b7a0ab1f51f328ff55aae3c1eb7789c31c28346696a8b1f27c7413c14e68fe977d3235b5a6f63c07d7a95d912ff22f17ad6", "This is the key used for encryption...");                

返回正确的纯文本。

顺便说一句:正如 Flydog57 已经声明 DES 是不安全的( https://en.wikipedia.org/wiki/Data_Encryption_Standard )。 而且 ECB 模式也不安全( https://crypto.stackexchange.com/questions/20941/why-shouldnt-i-use-ecb-encryption )。 更好的选择是 AES ( https://en.wikipedia.org/wiki/Advanced_Encryption_Standard ) 和 CBC 或 GCM 模式 ( https://crypto.stackexchange.com/questions/2310/what-is-the-difference-between-cbc -and-gcm-mode )。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM