• des加密算法java&c#


    项目中用到的数据加密方式是ECB模式的DES加密得到的十六进制字符串。技术支持让写一个.net版的加密算法。这里做一下记录。

    java版:

    16进制使用的是bouncycastle。

    import com.emaxcard.codec.CodecException;
    import com.emaxcard.codec.Hex;
    import sun.misc.BASE64Encoder;
    
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.spec.SecretKeySpec;
    
    public class DESEncrypt {
    
        public static String encodeECB(String src, String key) throws CodecException {
            try {
                SecretKey deskey = new SecretKeySpec(key.getBytes("UTF-8"), "DESede");
                Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
                cipher.init(Cipher.ENCRYPT_MODE, deskey);
                byte[] cipherInfo = cipher.doFinal(src.getBytes("UTF-8"));
                System.out.println("cipherInfo:"+new BASE64Encoder().encode(cipherInfo));
                return Hex.encode(cipherInfo);
            } catch (Exception var5) {
                throw new CodecException(var5);
            }
        }
    
        public static String decodeECB(String src, String key) throws CodecException {
            try {
                SecretKey deskey = new SecretKeySpec(key.getBytes("UTF-8"), "DESede");
                Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
                cipher.init(Cipher.DECRYPT_MODE, deskey);
                byte[] decodeRes = cipher.doFinal(Hex.decode(src));
                return new String(decodeRes, "UTF-8");
            } catch (Exception var5) {
                throw new CodecException(var5);
            }
        }
    }
    public class Hex {
        public Hex() {
        }
    
        public static byte[] decode(String data) throws CodecException {
            try {
                return org.bouncycastle.util.encoders.Hex.decode(data);
            } catch (Exception var2) {
                throw new CodecException(var2.getMessage(), var2);
            }
        }
    
        public static String encode(byte[] data) {
            return new String(org.bouncycastle.util.encoders.Hex.encode(data));
        }
    
        public static void main(String[] args) throws CodecException {
            System.out.println(encode("a张y".getBytes()));
            System.out.println(new String(decode("")));
        }
    }


    .net(c#)版:

    using System;
    using System.IO;
    using System.Security.Cryptography;
    using System.Text;
    
    namespace ConsoleApplication1
    {
        class DESEncrypt
        {
            public static string encodeECB(string encryptString, String key)
            {
                byte[] keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 8));
                byte[] keyIV = keyBytes;
                byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
                DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
                provider.Mode = CipherMode.ECB;
                provider.Padding = PaddingMode.PKCS7;
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, provider.CreateEncryptor(keyBytes, keyIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                //return Convert.ToBase64String(mStream.ToArray());
                return Hex.encode(mStream.ToArray());
            } 
            public static string DesDecrypt(string decryptString, String key)
            {
                byte[] keyBytes = Encoding.UTF8.GetBytes(key.Substring(0, 8));
                byte[] keyIV = keyBytes;
                //byte[] inputByteArray = Convert.FromBase64String(decryptString);
                byte[] inputByteArray = Hex.decode(decryptString);
                DESCryptoServiceProvider provider = new DESCryptoServiceProvider();
                provider.Mode = CipherMode.ECB;
                provider.Padding = PaddingMode.PKCS7;
                MemoryStream mStream = new MemoryStream();
                CryptoStream cStream = new CryptoStream(mStream, provider.CreateDecryptor(keyBytes, keyIV), CryptoStreamMode.Write);
                cStream.Write(inputByteArray, 0, inputByteArray.Length);
                cStream.FlushFinalBlock();
                return Encoding.UTF8.GetString(mStream.ToArray());
            }
    
        }
    }
    using System;
    using System.Globalization;
    using System.Text;
    
    namespace ConsoleApplication1
    {
        sealed class Hex
        {
            public static byte[] decode(String mHex)
            {
                mHex = mHex.Replace(" ", "");
                if (mHex.Length <= 0) return null;
                byte[] vBytes = new byte[mHex.Length / 2];
                for (int i = 0; i < mHex.Length; i += 2)
                    if (!byte.TryParse(mHex.Substring(i, 2), NumberStyles.HexNumber, null, out vBytes[i / 2]))
                        vBytes[i / 2] = 0;
                return vBytes;
            }
    
            public static String encode(byte[] data)
            {
                //**  以下两种方式都可以
                //方式1
                StringBuilder hexString = new StringBuilder();
                for (int i = 0; i < data.Length; i++)
                {
                    hexString.AppendFormat("{0:x2}", data[i]); //System.Convert.ToString(data[i], 16);
                }
                return hexString.ToString();
                //方式2
                //return BitConverter.ToString(data).Replace("-", "").ToLower();
            }
    
        }
    }


    BitConverter.ToString方法签名:

        //
        // 摘要: 
        //     将指定的字节数组的每个元素的数值转换为它的等效十六进制字符串表示形式。
        //
        // 参数: 
        //   value:
        //     字节数组。
        //
        // 返回结果: 
        //     由以连字符分隔的十六进制对构成的字符串,其中每一对表示 value 中对应的元素;例如“7F-2C-4A”。
        //
        // 异常: 
        //   System.ArgumentNullException:
        //     value 为 null。
        public static string ToString(byte[] value);

    关于DES

    DES是一种对称加密算法,所谓对称加密算法即:加密和解密使用相同密钥的算法。与之对应的是非对称加密算法,例如RSA,它是公钥加密并且私钥解密。

    des加密算法有如下几个要素:

    1. DES加密模式:这里选ECB
    2. 填充:java是pkcs5padding,.net是pkcs7padding。网上说PKCS5Padding与PKCS7Padding基本上是可以通用的。
    3. 字符集:utf-8
    4. 输出:base64、hex
    5. 密码/Key:8个字符(共64位)------java要求传24个字符,不过加密也是截取的前8位
    6. 待加密/解密的文本

    在线des加密工具:http://tool.chacuo.net/cryptdes

    注意:当DES加密使用的key与解密使用的key不一样时,会报这个异常。

    javax.crypto.BadPaddingException: Given final block not properly padded
    	at com.emaxcard.codec.Desede.decodeECB(Desede.java:151)

    ref:https://www.cnblogs.com/langtianya/p/3715975.html

  • 相关阅读:
    经典面试题目C语言
    论C语言中二级指针和二维数组之间的区别
    判断单链表中是否有环找到环的入口节点
    论decltype和auto的区别
    在ubuntu下安装opencv
    C中有关引用和指针的异同
    (四)关于读文件的结束的判别方法(EOF和feof)以及区别
    (三)论sizeof与strlen之间的区别
    (二)C语言文本流和二进制流的区别
    (一)C的编译,printf,规范化
  • 原文地址:https://www.cnblogs.com/buguge/p/10402992.html
Copyright © 2020-2023  润新知