注意点:
1.由于密钥、明文、密文的输入输出参数,都是byte数组(byte[]),所以:字符串转byte数组(byte[])环节,双方要约定好编码。
2. KEY 和 IV 从字符串转byte数组(byte[])时,双方要约定好编码,一般是UTF8。
3.明文从字符串转byte数组(byte[])时,双方要约定好编码,一般是UTF8,.NET 这边要注意:不能用 Encoding.Default。
4.加密后的结果,从byte数组(byte[])转字符串时,双方要约定好编码,一般是Base64字符串。
5.NET 的PKCS7Padding 对应 JAVA 的:PKCS5Padding
一、 .NET DES
先看工具类:DesUtil
- using System;
- using System.Security.Cryptography;
- using System.Text;
- namespace CommonUtils
- {
- /// <summary>
- /// 工具类,2024-06-16,runliuv。
- /// </summary>
- public class DesUtil
- {
- public static byte[] DesEncryptCBC(byte[] plainText, byte[] Key, byte[] IV)
- {
- byte[] encrypted;
- using (DESCryptoServiceProvider desAlg = new DESCryptoServiceProvider())
- {
- desAlg.Key = Key;
- desAlg.IV = IV;
- desAlg.Mode = CipherMode.CBC;
- desAlg.Padding = PaddingMode.PKCS7;
- using (ICryptoTransform encryptor = desAlg.CreateEncryptor())
- {
- encrypted= encryptor.TransformFinalBlock(plainText, 0, plainText.Length);
- }
- }
- return encrypted;
- }
- public static byte[] DesDecryptCBC(byte[] cipherText, byte[] Key, byte[] IV)
- {
- byte[] plaintext = null;
- using (DESCryptoServiceProvider desAlg = new DESCryptoServiceProvider())
- {
- desAlg.Key = Key;
- desAlg.IV = IV;
- desAlg.Mode = CipherMode.CBC;
- desAlg.Padding = PaddingMode.PKCS7;
- using (ICryptoTransform decryptor = desAlg.CreateDecryptor())
- {
- plaintext = decryptor.TransformFinalBlock(cipherText, 0, cipherText.Length);
- }
- }
- return plaintext;
- }
- /// <summary>
- /// DES CBC 加密
- /// </summary>
- /// <param name="plainText">明文</param>
- /// <param name="Key">密钥</param>
- /// <param name="IV"></param>
- /// <returns></returns>
- public static string DesEncryptCBC(string plainText, string Key, string IV)
- {
- byte[] yy= DesEncryptCBC(Encoding.UTF8.GetBytes(plainText), Encoding.UTF8.GetBytes(Key), Encoding.UTF8.GetBytes(IV));
- string xx=Convert.ToBase64String(yy);
- return xx;
- }
- /// <summary>
- /// DES CBC 解密
- /// </summary>
- /// <param name="cipherText">密文</param>
- /// <param name="Key">密钥</param>
- /// <param name="IV"></param>
- /// <returns></returns>
- public static string DesDecryptCBC(string cipherText, string Key, string IV)
- {
- byte[] yy = DesDecryptCBC(Convert.FromBase64String(cipherText), Encoding.UTF8.GetBytes(Key), Encoding.UTF8.GetBytes(IV));
- string xx = Encoding.UTF8.GetString(yy);
- return xx;
- }
- }
- }
.NET 使用这个工具类,做DES CBC 加密 :
- static void TestDesCbc()
- {
- Console.WriteLine("-- Test Cbc --");
- string aesKey = "12345678";// DES 密钥长度是8位
- string aesIV = "abcdefgh";// DES IV长度是8位
-
- string orgStr = "hello .net 2024-06-10";
- string encryptedStr = DesUtil.DesEncryptCBC(orgStr, aesKey, aesIV);
- Console.WriteLine("加密字符串:" + encryptedStr);
- //自加,自解
- string decryptedStr = DesUtil.DesDecryptCBC(encryptedStr, aesKey, aesIV);
- Console.WriteLine("自加,自解:" + decryptedStr);
- }
.NET 输出结果 :
- -- Test Cbc --
- 加密字符串:yxEOkYM81hdv0bC1EwgCdE1JSsFyW70A
- 自加,自解:hello .net 2024-06-10
- 结束 。

.NET 简要说明:
加密:
- public static string DesEncryptCBC(string plainText, string Key, string IV)
- {
- byte[] yy= DesEncryptCBC(Encoding.UTF8.GetBytes(plainText), Encoding.UTF8.GetBytes(Key), Encoding.UTF8.GetBytes(IV));
- string xx=Convert.ToBase64String(yy);
- return xx;
- }
Encoding.UTF8.GetBytes(plainText),明文字符串转byte数组 使用UTF8。
Encoding.UTF8.GetBytes(Key), Encoding.UTF8.GetBytes(IV),KEY 和 IV 转byte数组 使用UTF8。
- public static byte[] DesEncryptCBC(byte[] plainText, byte[] Key, byte[] IV)
- {
- byte[] encrypted;
- using (DESCryptoServiceProvider desAlg = new DESCryptoServiceProvider())
- {
- desAlg.Key = Key;
- desAlg.IV = IV;
- desAlg.Mode = CipherMode.CBC;
- desAlg.Padding = PaddingMode.PKCS7;
- using (ICryptoTransform encryptor = desAlg.CreateEncryptor())
- {
- encrypted= encryptor.TransformFinalBlock(plainText, 0, plainText.Length);
- }
- }
- return encrypted;
- }
创建一个DESCryptoServiceProvider对象,指定KEY 和 IV,指定 加密模式和 PADDING。
创建加密器对象:desAlg.CreateEncryptor()。
使用 TransformFinalBlock 算出加密结果。
string xx=Convert.ToBase64String(yy); 加密后的结果转字符串时,使用Base64字符串。
解密:
- public static string DesDecryptCBC(string cipherText, string Key, string IV)
- {
- byte[] yy = DesDecryptCBC(Convert.FromBase64String(cipherText), Encoding.UTF8.GetBytes(Key), Encoding.UTF8.GetBytes(IV));
- string xx = Encoding.UTF8.GetString(yy);
- return xx;
- }
Convert.FromBase64String(cipherText),由于加密结果集转字符串时用的base64,所以密文转byte数组时,就要用Convert.FromBase64String。

KEY 和 IV 就不用多说了。
- public static byte[] DesDecryptCBC(byte[] cipherText, byte[] Key, byte[] IV)
- {
- byte[] plaintext = null;
- using (DESCryptoServiceProvider desAlg = new DESCryptoServiceProvider())
- {
- desAlg.Key = Key;
- desAlg.IV = IV;
- desAlg.Mode = CipherMode.CBC;
- desAlg.Padding = PaddingMode.PKCS7;
- using (ICryptoTransform decryptor = desAlg.CreateDecryptor())
- {
- plaintext = decryptor.TransformFinalBlock(cipherText, 0, cipherText.Length);
- }
- }
- return plaintext;
- }
创建一个DESCryptoServiceProvider对象,指定KEY 和 IV,指定 模式和 PADDING。
创建解密器对象:desAlg.CreateDecryptor()。
使用 TransformFinalBlock 解密出结果。
string xx = Encoding.UTF8.GetString(yy); 加密时,明文转byte[] 时用的UTF8,那解密出的明文结果,转byte数组时,也得用UTF8。

可以说,解密与加密是相反的。

二、JAVA DES
还是简要封装个工具类DesUtil。
- package org.runliuv;
- import javax.crypto.Cipher;
- import javax.crypto.spec.IvParameterSpec;
- import javax.crypto.spec.SecretKeySpec;
- import java.util.Base64;
- public class DesUtil {
- private static final String charset = "UTF-8";
- public static String DesEncryptCBC(String content, String key, String iv)
- throws Exception {
- //明文
- byte[] contentBytes = content.getBytes(charset);
- //DES KEY
- byte[] keyBytes = key.getBytes(charset);
- SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "DES");
- //DES IV
- byte[] initParam = iv.getBytes(charset);
- IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);
- Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
- cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivParameterSpec);
- byte[] byEnd = cipher.doFinal(contentBytes);
- //加密后的byte数组转BASE64字符串
- String strEnd = Base64.getEncoder().encodeToString(byEnd);
- return strEnd;
- }
- /**
- * 解密
- * @param content
- * @param key
- * @param iv
- * @return
- * @throws Exception
- */
- public static String DesDecryptCBC(String content, String key, String iv)
- throws Exception {
- //反向解析BASE64字符串为byte数组
- byte[] encryptedBytes = Base64.getDecoder().decode(content);
- //DES KEY
- byte[] keyBytes = key.getBytes(charset);
- SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "DES");
- //DES IV
- byte[] initParam = iv.getBytes(charset);
- IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);
- Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
- cipher.init(Cipher.DECRYPT_MODE, keySpec, ivParameterSpec);
- byte[] byEnd = cipher.doFinal(encryptedBytes);
- //加密后的byte数组直接转字符串
- String strEnd = new String(byEnd, charset);
- return strEnd;
- }
- }
JAVA 使用工具类进行 DES CBC 加密,解密:
- System.out.println("-- Test Cbc --");
- String aesKey = "12345678";// DES 密钥长度是8位
- String aesIV = "abcdefgh";// DES IV长度是8位
- String orgStr = "hello JAVA 2024-06-10";
- System.out.println("待加密字符串:" + orgStr);
- String encryptedStr = DesUtil.DesEncryptCBC(orgStr, aesKey, aesIV);
- System.out.println("加密后:" + encryptedStr);
- //自加,自解
- String decryptedStr = DesUtil.DesDecryptCBC(encryptedStr, aesKey, aesIV);
- System.out.println("自加,自解:" + decryptedStr);
效果:
- -- Test Cbc --
- 待加密字符串:hello JAVA 2024-06-10
- 加密后:VkxvjXu1YKvQJF8MPnFvXhFzJgZI4j9I
- 自加,自解:hello JAVA 2024-06-10

三、.NET 加 JAVA 解
先用.NET 对"hello .net 2024-06-10",这个字符串加密,KEY是"12345678",IV为“abcdefgh”,加密结果为:
yxEOkYM81hdv0bC1EwgCdE1JSsFyW70A
将这个串复制到JAVA代码,进行解密:
- String NETStr ="yxEOkYM81hdv0bC1EwgCdE1JSsFyW70A";
- System.out.println(".NET 加密后的串:" + NETStr);
- String decryptedStr = DesUtil.DesDecryptCBC(NETStr, aesKey, aesIV);
- System.out.println("JAVA解密:" + decryptedStr);
输出结果 :
- -- Test Cbc --
- .NET 加密后的串:yxEOkYM81hdv0bC1EwgCdE1JSsFyW70A
- JAVA解密:hello .net 2024-06-10

--
DES ECB 的加密模式,请自行探索。