3DESC加密算法
阅读原文时间:2023年07月14日阅读:1

3DESC

请求参数和响应参数全采用3des加密规则,由于我是用.NET对接的,而第三方是Java开发的,所以两种程序之间采用的算法有一点差异,java的3des加密采用的是"DESede/CBC/PKCS5Padding"规则,所以对应的C#规则是"PaddingMode.PKCS7和CipherMode.CBC",使用CBC模式的话在C#下必须传入加密向量IV(固定长度8位),默认"12345678",加密密钥和IV双方约定好即可,如果是ECB编码模式,那么就无须使用加密向量。

这里的KEY采用Base64编码,便用分发,因为Java的Byte范围为-128至127,c#的Byte范围是0-255
核心是确定Mode和Padding,关于这两个的意思可以搜索3DES算法相关文章
一个是C#采用CBC Mode,PKCS7 Padding,Java采用CBC Mode,PKCS5Padding Padding,
另一个是C#采用ECB Mode,PKCS7 Padding,Java采用ECB Mode,PKCS5Padding Padding,
Java的ECB模式不需要IV

对字符加密时,双方采用的都是UTF-8编码

DesIv: 3FEB40B6
DesKey: 3FD5F52BEA57D4B03FE9CF73

///

/// DES3加密解密 ///
public class Des3
{
#region CBC模式**
/// /// DES3 CBC模式加密 ///
/// 密钥
/// IV
/// 明文的byte数组
/// 密文的byte数组
public static byte[] Des3EncodeCBC( byte[] key, byte[] iv, byte[] data )
{
//复制于MSDN
try
{
// Create a MemoryStream.
MemoryStream mStream = new MemoryStream();
TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
tdsp.Mode = CipherMode.CBC; //默认值
tdsp.Padding = PaddingMode.PKCS7; //默认值
// Create a CryptoStream using the MemoryStream
// and the passed key and initialization vector (IV).
CryptoStream cStream = new CryptoStream( mStream,
tdsp.CreateEncryptor( key, iv ),
CryptoStreamMode.Write );
// Write the byte array to the crypto stream and flush it.
cStream.Write( data, , data.Length );
cStream.FlushFinalBlock();
// Get an array of bytes from the
// MemoryStream that holds the
// encrypted data.
byte[] ret = mStream.ToArray();
// Close the streams.
cStream.Close();
mStream.Close();
// Return the encrypted buffer.
return ret;
}
catch ( CryptographicException e )
{
Console.WriteLine( "A Cryptographic error occurred: {0}", e.Message );
return null;
}
}
/// /// DES3 CBC模式解密 ///
/// 密钥
/// IV
/// 密文的byte数组
/// 明文的byte数组
public static byte[] Des3DecodeCBC( byte[] key, byte[] iv, byte[] data )
{
try
{
// Create a new MemoryStream using the passed
// array of encrypted data.
MemoryStream msDecrypt = new MemoryStream( data );
TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
tdsp.Mode = CipherMode.CBC;
tdsp.Padding = PaddingMode.PKCS7;
// Create a CryptoStream using the MemoryStream
// and the passed key and initialization vector (IV).
CryptoStream csDecrypt = new CryptoStream( msDecrypt,
tdsp.CreateDecryptor( key, iv ),
CryptoStreamMode.Read );
// Create buffer to hold the decrypted data.
byte[] fromEncrypt = new byte[data.Length];
// Read the decrypted data out of the crypto stream
// and place it into the temporary buffer.
csDecrypt.Read( fromEncrypt, , fromEncrypt.Length );
//Convert the buffer into a string and return it.
return fromEncrypt;
}
catch ( CryptographicException e )
{
Console.WriteLine( "A Cryptographic error occurred: {0}", e.Message );
return null;
}
}
#endregion
#region ECB模式
/// /// DES3 ECB模式加密 ///
/// 密钥
/// IV(当模式为ECB时,IV无用)
/// 明文的byte数组
/// 密文的byte数组
public static byte[] Des3EncodeECB( byte[] key, byte[] iv, byte[] data )
{
try
{
// Create a MemoryStream.
MemoryStream mStream = new MemoryStream();
TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
tdsp.Mode = CipherMode.ECB;
tdsp.Padding = PaddingMode.PKCS7;
// Create a CryptoStream using the MemoryStream
// and the passed key and initialization vector (IV).
CryptoStream cStream = new CryptoStream( mStream,
tdsp.CreateEncryptor( key, iv ),
CryptoStreamMode.Write );
// Write the byte array to the crypto stream and flush it.
cStream.Write( data, , data.Length );
cStream.FlushFinalBlock();
// Get an array of bytes from the
// MemoryStream that holds the
// encrypted data.
byte[] ret = mStream.ToArray();
// Close the streams.
cStream.Close();
mStream.Close();
// Return the encrypted buffer.
return ret;
}
catch ( CryptographicException e )
{
Console.WriteLine( "A Cryptographic error occurred: {0}", e.Message );
return null;
}
}
/// /// DES3 ECB模式解密 ///
/// 密钥
/// IV(当模式为ECB时,IV无用)
/// 密文的byte数组
/// 明文的byte数组
public static byte[] Des3DecodeECB( byte[] key, byte[] iv, byte[] data )
{
try
{
// Create a new MemoryStream using the passed
// array of encrypted data.
MemoryStream msDecrypt = new MemoryStream( data );
TripleDESCryptoServiceProvider tdsp = new TripleDESCryptoServiceProvider();
tdsp.Mode = CipherMode.ECB;
tdsp.Padding = PaddingMode.PKCS7;
// Create a CryptoStream using the MemoryStream
// and the passed key and initialization vector (IV).
CryptoStream csDecrypt = new CryptoStream( msDecrypt,
tdsp.CreateDecryptor( key, iv ),
CryptoStreamMode.Read );
// Create buffer to hold the decrypted data.
byte[] fromEncrypt = new byte[data.Length];
// Read the decrypted data out of the crypto stream
// and place it into the temporary buffer.
csDecrypt.Read( fromEncrypt, , fromEncrypt.Length );
//Convert the buffer into a string and return it.
return fromEncrypt;
}
catch ( CryptographicException e )
{
Console.WriteLine( "A Cryptographic error occurred: {0}", e.Message );
return null;
}
}
#endregion
/// /// 类测试 ///
public static void Test()
{
System.Text.Encoding utf8 = System.Text.Encoding.UTF8;
//key为abcdefghijklmnopqrstuvwx的Base64编码
byte[] key = Convert.FromBase64String( "YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4" );
byte[] iv = new byte[] { , , , , , , , }; //当模式为ECB时,IV无用
byte[] data = utf8.GetBytes( "中国ABCabc123" );
System.Console.WriteLine( "ECB模式:" );
byte[] str1 = Des3.Des3EncodeECB( key, iv, data );
byte[] str2 = Des3.Des3DecodeECB( key, iv, str1 );
System.Console.WriteLine( Convert.ToBase64String( str1 ) );
System.Console.WriteLine( System.Text.Encoding.UTF8.GetString( str2 ) );
System.Console.WriteLine();
System.Console.WriteLine( "CBC模式:" );
byte[] str3 = Des3.Des3EncodeCBC( key, iv, data );
byte[] str4 = Des3.Des3DecodeCBC( key, iv, str3 );
System.Console.WriteLine( Convert.ToBase64String( str3 ) );
System.Console.WriteLine( utf8.GetString( str4 ) );
System.Console.WriteLine();
}
}

C# 3DESC

package com.mes.util;

import java.security.Key;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;

import sun.misc.BASE64Decoder;

@SuppressWarnings("restriction")
public class ThreeDESCBC {
/**
*
* @Description ECB加密,不要IV
* @param key 密钥
* @param data 明文
* @return Base64编码的密文
* @throws Exception
* @author Shindo
* @date 2016年11月15日 下午4:42:56
*/
public static byte[] des3EncodeECB(byte[] key, byte[] data) throws Exception {
Key deskey = null;
DESedeKeySpec spec = new DESedeKeySpec(key);
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
deskey = keyfactory.generateSecret(spec);
Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, deskey);
byte[] bOut = cipher.doFinal(data);
return bOut;
}

/\*\*  
 \*  
 \* @Description ECB解密,不要IV  
 \* @param key 密钥  
 \* @param data Base64编码的密文  
 \* @return 明文  
 \* @throws Exception  
 \* @author Shindo  
 \* @date 2016年11月15日 下午5:01:23  
 \*/  
public static byte\[\] ees3DecodeECB(byte\[\] key, byte\[\] data) throws Exception {  
    Key deskey = null;  
    DESedeKeySpec spec = new DESedeKeySpec(key);  
    SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");  
    deskey = keyfactory.generateSecret(spec);  
    Cipher cipher = Cipher.getInstance("desede" + "/ECB/PKCS5Padding");  
    cipher.init(Cipher.DECRYPT\_MODE, deskey);  
    byte\[\] bOut = cipher.doFinal(data);  
    return bOut;  
}

/\*\*  
 \*  
 \* @Description CBC加密  
 \* @param key 密钥  
 \* @param keyiv IV  
 \* @param data 明文  
 \* @return Base64编码的密文  
 \* @throws Exception  
 \* @author Shindo  
 \* @date 2016年11月15日 下午5:26:46  
 \*/  
public static byte\[\] des3EncodeCBC(byte\[\] key, byte\[\] keyiv, byte\[\] data) throws Exception {  
    Key deskey = null;  
    DESedeKeySpec spec = new DESedeKeySpec(key);  
    SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");  
    deskey = keyfactory.generateSecret(spec);  
    Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding");  
    IvParameterSpec ips = new IvParameterSpec(keyiv);  
    cipher.init(Cipher.ENCRYPT\_MODE, deskey, ips);  
    byte\[\] bOut = cipher.doFinal(data);  
    return bOut;  
}

/\*\*  
 \*  
 \* @Description CBC解密  
 \* @param key 密钥  
 \* @param keyiv IV  
 \* @param data Base64编码的密文  
 \* @return 明文  
 \* @throws Exception  
 \* @author Shindo  
 \* @date 2016年11月16日 上午10:13:49  
 \*/  
public static byte\[\] des3DecodeCBC(byte\[\] key, byte\[\] keyiv, byte\[\] data) throws Exception {  
    Key deskey = null;  
    DESedeKeySpec spec = new DESedeKeySpec(key);  
    SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");  
    deskey = keyfactory.generateSecret(spec);  
    Cipher cipher = Cipher.getInstance("desede" + "/CBC/PKCS5Padding");  
    IvParameterSpec ips = new IvParameterSpec(keyiv);  
    cipher.init(Cipher.DECRYPT\_MODE, deskey, ips);  
    byte\[\] bOut = cipher.doFinal(data);  
    return bOut;  
}

/\*\*  
 \*  
 \* @Description 浦发所属渠道入口3DES解密方法  
 \* @param paras 加密参数  
 \* @param key 3DES密钥  
 \* @return 解密明文  
 \* @author Shindo  
 \* @throws Exception  
 \* @date 2016年11月22日 上午9:34:07  
 \*/  
public Map<String, String> parasDecryptCBC(Map<String, String> paras, String key) throws Exception {  
    Map<String, String> map = new HashMap<String, String>();  
    try {  
        byte\[\] pf\_3des\_key = new BASE64Decoder().decodeBuffer(key);  
        byte\[\] keyiv = { , , , , , , ,  };// 3DES解密IV值  
        String telePhone = paras.get("telePhone");// 浦发新接口电话不加密

        byte\[\] card = new BASE64Decoder().decodeBuffer(ControllerUtils.URLDecode(paras.get("cardNo")));  
        byte\[\] cert = new BASE64Decoder().decodeBuffer(ControllerUtils.URLDecode(paras.get("certNo")));

        String cardNo = new String(des3DecodeCBC(pf\_3des\_key, keyiv, card), "UTF-8");// 卡号  
        String certNo = new String(des3DecodeCBC(pf\_3des\_key, keyiv, cert), "UTF-8");// 证件号码  
        map.put("telePhone", telePhone);  
        map.put("cardNo", cardNo);  
        map.put("certNo", certNo);  
    } catch (Exception e) {  
        throw new Exception(" 浦发所属渠道入口参数3DES CBC解密失败!");  
    }  
    return map;  
}

/\*\*  
 \*  
 \* @Description 调试方法  
 \* @param args  
 \* @throws Exception  
 \* @author Shindo  
 \* @date 2016年11月22日 上午9:28:22  
 \*/  
public static void main(String\[\] args) throws Exception {  
    byte\[\] key = new BASE64Decoder().decodeBuffer("YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4");  
    byte\[\] keyiv = { , , , , , , ,  };  

// byte[] data = "420106198203279258".getBytes("UTF-8");
/*System.out.println("ECB加密解密");
byte[] str3 = des3EncodeECB(key, data);
byte[] str4 = ees3DecodeECB(key, str3);
System.out.println(new BASE64Encoder().encode(str3));
System.out.println(new String(str4, "UTF-8"));
System.out.println();*/

    /\*System.out.println("CBC加密解密");  
    byte\[\] str5 = des3EncodeCBC(key, keyiv, data);  
    byte\[\] str6 = des3DecodeCBC(key, keyiv, str5);  
    System.out.println(new BASE64Encoder().encode(str5));  
    System.out.println(new String(str6, "UTF-8"));\*/

    String str7 = "uHrew7Thp2taL2NJpSJhF2mdFMP7BZ1W";  
    byte\[\] str8 = new BASE64Decoder().decodeBuffer(str7);  
    byte\[\] str9 = des3DecodeCBC(key, keyiv, str8);  
    System.out.println(new String(str9, "UTF-8"));

}

}

JAVA 3DESC

转:https://www.cnblogs.com/shindo/p/6346655.html