C#和JAVA 3DES的CBC模式加密解密

最近因为需要和外部系统进行通信,数据交互基于3DES的CBC模式。因为2种语言对算法的实现有差异性,一开始准备面向搜索引擎编程的,结果发现网上的解决方案都不能使用, 全部报错!Google也翻了50页,最终无奈自己实现了。废话不多说直接上代码!

C#代码

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace HM.Framework
{
    /// 
    /// 加密工具类
    /// 
    public static class EncryUtils
    {
        /// 
        /// 3DES加密CBC模式
        /// 
        /// 明文(待加密)
        /// 加密密钥
        /// 向量
        /// 
        public static string TripleDesEncryptorCBC(string text, string key, string iv)
        {
            var tripleDESCipher = new TripleDESCryptoServiceProvider();
            tripleDESCipher.Mode = CipherMode.CBC;
            tripleDESCipher.Padding = PaddingMode.PKCS7;
            byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(key);
            byte[] keyBytes = new byte[24];
            int len = pwdBytes.Length;
            if (len > keyBytes.Length)
                len = keyBytes.Length;
            System.Array.Copy(pwdBytes, keyBytes, len);
            tripleDESCipher.Key = keyBytes;
            tripleDESCipher.IV = Encoding.ASCII.GetBytes(iv);

            ICryptoTransform transform = tripleDESCipher.CreateEncryptor();
            byte[] plainText = Encoding.UTF8.GetBytes(text);
            byte[] cipherBytes = transform.TransformFinalBlock(plainText, 0, plainText.Length);
            return Convert.ToBase64String(cipherBytes);
        }

        /// 
        /// 3DES解密CBC模式
        /// 
        /// 
        /// 
        /// 
        /// 
        public static string TripleDesDecryptorCBC(string text,string key,string iv)
        {
            var tripleDESCipher = new TripleDESCryptoServiceProvider();
            tripleDESCipher.Mode = CipherMode.CBC;
            tripleDESCipher.Padding = PaddingMode.PKCS7;
            
            byte[] encryptedData = Convert.FromBase64String(text);
            byte[] pwdBytes = System.Text.Encoding.UTF8.GetBytes(key);
            byte[] keyBytes = new byte[24];
            byte[] ivBytes = Encoding.ASCII.GetBytes(iv);
            int len = pwdBytes.Length;
            if (len > keyBytes.Length)
                len = keyBytes.Length;
            System.Array.Copy(pwdBytes, keyBytes, len);
            tripleDESCipher.Key = keyBytes;          
            tripleDESCipher.IV = ivBytes;
            ICryptoTransform transform = tripleDESCipher.CreateDecryptor();
            byte[] plainText = transform.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
            return Encoding.UTF8.GetString(plainText);
        }

        /// 
        /// 类测试
        /// 
        public static void Test()
        {
            var text = "AAABBBCCC啦啦啦啦AABB11";
            var key = "PR3tmPJqcH5RE0iGsW4qiN5VYtjX7sVU";
            var iv = "87654321";


            var encryptData = EncryUtils.TripleDesEncryptorCBC(text, key, iv);
            var decryptorData = EncryUtils.TripleDesDecryptorCBC(encryptData, key, iv);
            Console.WriteLine("原始字符串:{0}", text);
            Console.WriteLine("加密后的值:{0}", encryptData);
            Console.WriteLine("解密后的值:{0}", decryptorData);
        }
    
    }
}

JAVA代码

package com.songm.pcp.common.util;


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

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

import org.apache.commons.codec.binary.Hex;


public class Des {

    // 向量
    private final static String iv = "87654321";
    // 加解密统一使用的编码方式
    private final static String encoding = "UTF-8";
    /**
     * 3DES加密
     * @param plainText 普通文本
     * @param secretKey
     * @return
     * @throws Exception
     */
    public static String encode(String plainText,String secretKey){
        try{
            Key deskey = null;
            DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
            SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
            deskey = keyfactory.generateSecret(spec);

            Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
            IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
            cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
            byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
            return Base64Utils.encode(encryptData);
            //byte[] bb =  Base64Utils.encode(encryptData);
           
           // return new String(bb,"UTF-8");
        }catch(Exception e){
            e.printStackTrace();
        }
        return plainText;
    }

    /**
     * 3DES解密
     *
     * @param encryptText 加密文本
     * @return
     * @throws Exception
     */
    public static String decode(String encryptText,String secretKey){
        try{
            Key deskey = null;
            DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
            SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
            deskey = keyfactory.generateSecret(spec);
            Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
            IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
            cipher.init(Cipher.DECRYPT_MODE, deskey, ips);

            //byte[] decryptData = cipher.doFinal(Des3Base64.decode(encryptText));
            byte[] decryptData = cipher.doFinal(Base64Utils.decode(encryptText));
            return new String(decryptData, encoding);
        }catch(Exception e){
            e.printStackTrace();
        }
        return encryptText;
    }

    
    public static void main(String[] args) {

        String text = "AAABBBCCC啦啦啦啦AABB11";
        String key = "PR3tmPJqcH5RE0iGsW4qiN5VYtjX7sVU";
        String encryptData = encode(text, key);
        String decryptorData = decode(encryptData, key);
        System.out.println("原始字符串:" + text);
        System.out.println("加密后的值" + encryptData);
        System.out.println("解密后的值" + decryptorData);
    }
        
}

你可能感兴趣的:(C#和JAVA 3DES的CBC模式加密解密)