美文网首页
各个平台DES加密方式的实现

各个平台DES加密方式的实现

作者: Coder蒋 | 来源:发表于2019-07-22 17:23 被阅读0次

    背景

    前段时间在跟后台联调敏感数据的加密和解密时遇到了一些问题,设备使用的是android平台提供的des加密方式,后台使用的javax提供的des加密方式和PHP提供加密方式,在对接过程中就出现了同一段字符,在前后端解密得到的字符串不一样,最后经过一段时间的调试,得到了结果一致的实现方式,下面记录下来。

    实现平台

    java平台

    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.DESKeySpec;
    import java.util.Base64;
     
    public class DESUtil {
     
        private static final String KEY = "test";
        private static final String DES = "DES";
        private static final String DES_P = "DES/ECB/PKCS5Padding";
        private static final String CHARSET = "UTF-8";
     
     
        /**
         * 进行DES加密
         *
         * @param string String 需要加密的字符串
         * @return String 加密字符串
         */
        public static String encryptByDes(String string) {
            return encryptByDes(string, KEY);
        }
     
     
        /**
         * DES 解密
         *
         * @param string String 加密串
         * @return String 明文
         */
        public static String decryptByDes(String string) {
            return decryptByDes(string, KEY);
        }
     
     
        /**
         * 进行DES加密
         *
         * @param string
         * @param key
         * @return
         */
        private static String encryptByDes(String string, String key) {
            try {
                if (string != null && string.length() > 0) {
                    byte[] tmpOriginalStr = string.getBytes(CHARSET);
                    // 创建一个密匙工厂
                    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
                    // 创建一个DESKeySpec对象
                    DESKeySpec dks = new DESKeySpec(key.getBytes());
                    // 将DESKeySpec对象转换成SecretKey对象
                    SecretKey secretKey = keyFactory.generateSecret(dks);
                    // 用密匙初始化Cipher对象
                    Cipher cipher = Cipher.getInstance(DES_P);
                    // Cipher对象实际完成加密操作
                    cipher.init(Cipher.ENCRYPT_MODE, secretKey);
                    // 真正开始加密操作
                    byte[] encryptStr = cipher.doFinal(tmpOriginalStr);
                    if (encryptStr != null) {
                        return Base64.getEncoder().encodeToString(encryptStr);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
     
        /**
         * DES 解密
         *
         * @param string
         * @param key
         * @return
         */
        private static String decryptByDes(String string, String key) {
            try {
                if (string != null && string.length() > 0) {
                    // 创建一个密匙工厂
                    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
                    // 创建一个DESKeySpec对象
                    DESKeySpec dks = new DESKeySpec(key.getBytes(CHARSET));
                    // 将DESKeySpec对象转换成SecretKey对象
                    SecretKey secretKey = keyFactory.generateSecret(dks);
                    // 用密匙初始化Cipher对象
                    Cipher cipher = Cipher.getInstance(DES_P);
                    // Cipher对象实际完成解密操作
                    cipher.init(Cipher.DECRYPT_MODE, secretKey);
                    // 真正开始解密操作
                    byte[] decryptBytes = cipher.doFinal(Base64.getDecoder().decode(string));
                    if (decryptBytes != null) {
                        return new String(decryptBytes, CHARSET);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    }
    

    android平台

    /**
     * DES 工具类
     */
    public class DESUtil {
        @IntDef({Cipher.ENCRYPT_MODE, Cipher.DECRYPT_MODE})
        @interface DESType {}
    
        /**
         * Des加密/解密
         *
         * @param content  字符串内容
         * @param password 密钥
         * @param type     加密:{@link Cipher#ENCRYPT_MODE},解密:{@link Cipher#DECRYPT_MODE}
         * @return 加密/解密结果
         */
        public static String des(String content, String password, @DESType int type) {
            try {
                SecureRandom random = new SecureRandom();
                DESKeySpec desKey = new DESKeySpec(password.getBytes());
                SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
                @SuppressLint("GetInstance") Cipher cipher = Cipher.getInstance("DES");
                cipher.init(type, keyFactory.generateSecret(desKey), random);
    
                if (type == Cipher.ENCRYPT_MODE) {
                    byte[] byteContent = content.getBytes("utf-8");
                    return parseByte2HexStr(cipher.doFinal(byteContent));
                } else {
                    byte[] byteContent = parseHexStr2Byte(content);
                    return new String(cipher.doFinal(byteContent));
                }
            } catch (NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException |
                    UnsupportedEncodingException | InvalidKeyException | NoSuchPaddingException |
                    InvalidKeySpecException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * des加密
         *
         * @param plainText 待加密字符串
         * @return 加密后的字符串
         */
        public static String encryptByDes(String plainText){
    
            return EncryptionClient.encryptByDes(plainText);
        }
    
        /**
         * des解密
         *
         * @param cipherText 待解密字符串
         * @return 解密后的字符串
         */
        public static String decryptByDes(String cipherText) throws Exception{
    
            return EncryptionClient.decryptByDes(cipherText);
        }
    
    }
    

    ios平台

    #pragma mark- 加密算法
     
    +(NSString *) encryptUseDES:(NSString *)plainText key:(NSString *)key{
     
        NSString *ciphertext = nil;
        NSData *textData = [plainText dataUsingEncoding:NSUTF8StringEncoding];
        NSUInteger dataLength = [textData length];
        unsigned char buffer[1024];
        memset(buffer, 0, sizeof(char));
        size_t numBytesEncrypted = 0;
     
        CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
                                              kCCAlgorithmDES,
                                              kCCOptionPKCS7Padding | kCCOptionECBMode,
                                              [key UTF8String],
                                              kCCKeySizeDES,
                                              nil,
                                              [textData bytes],
                                              dataLength,
                                              buffer,
                                              1024,
                                              &numBytesEncrypted);
        if (cryptStatus == kCCSuccess) {
            NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];
            ciphertext = [GTMBase64 stringByEncodingData:data];
        }
        return ciphertext;
    }
    
    #pragma mark- 解密算法
     
    +(NSString *)decryptUseDES:(NSString *)cipherText key:(NSString *)key{
     
        NSString *plaintext = nil;
        NSData *cipherdata = [GTMBase64 decodeString:cipherText];
        unsigned char buffer[1024];
        memset(buffer, 0, sizeof(char));
        size_t numBytesDecrypted = 0;
        CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,
                                              kCCOptionPKCS7Padding | kCCOptionECBMode,
                                              [key UTF8String],
                                              kCCKeySizeDES,
                                              nil,
                                              [cipherdata bytes],
                                              [cipherdata length],
                                              buffer,
                                              1024,
                                              &numBytesDecrypted);
        if(cryptStatus == kCCSuccess) {
            NSData *plaindata = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesDecrypted];
            plaintext = [[NSString alloc]initWithData:plaindata encoding:NSUTF8StringEncoding];
        }
        return plaintext;
    }
    

    Web前端

    import CryptoJS from "crypto-js"
    KEY = 'test'
    function encodeData(data) {
        if (data) {
            let key = CryptoJS.enc.Utf8.parse(KEY);
            return CryptoJS.DES.encrypt(data, key, {
                padding: CryptoJS.pad.Pkcs7,
                mode: CryptoJS.mode.ECB
            }).toString()
        } else {
            return ""
        }
    }
    function decodeData(data) {
        if (data) {
            try {
                let key = CryptoJS.enc.Utf8.parse(KEY);
                return CryptoJS.DES.decrypt(data, key, {
                    padding: CryptoJS.pad.Pkcs7,
                    mode: CryptoJS.mode.ECB
                }).toString(CryptoJS.enc.Utf8)
            } catch (e) {
                return "decode failure"
            } finally {
            }
        } else {
            return ""
        }
    }
    

    C#平台

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Security.Cryptography;
    using System.Text;
    using System.Threading.Tasks;
    namespace SenseKeeperV3_guest_sample
    {
            /// <summary>
            /// 类名称   :CryptTools
            /// 类说明   :加解密算法
            /// 完成日期 :
            /// </summary>
            public static class CryptTools
            {
              
                private static string inlineKey = "test";
                #region DES加密字符串
                ///// <summary>
                /////
                ///// 注意:密钥必须为8位
                ///// </summary>
                /// <summary>
                /// 加密字符串
                /// </summary>
                /// <param name="p_strInput">明码</param>
                /// <returns>加密后的密码</returns>
                public static string DesEncryptFixKey(string p_strInput,string key)
                {
                    byte[] byKey = null;
                    byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
                    try
                    {
                        byKey = System.Text.Encoding.UTF8.GetBytes(key.Substring(0, 8));
                        DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                        des.Mode = CipherMode.ECB;
                        byte[] inputByteArray = Encoding.UTF8.GetBytes(p_strInput);
                        MemoryStream ms = new MemoryStream();
                        CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(byKey, IV), CryptoStreamMode.Write);
                        cs.Write(inputByteArray, 0, inputByteArray.Length);
                        cs.FlushFinalBlock();
                        return Convert.ToBase64String(ms.ToArray());
                    }
                    catch (System.Exception ex)
                    {
                        throw (ex);
                    }
                }
                #endregion
                #region DES解密字符串
                //const string m_strEncryptKey = "kinghuns"; zh注释
                /// <summary>
                /// 解密字符串
                /// </summary>
                /// <param name="this.inputString">加了密的字符串</param>
                /// <param name="decryptKey">密钥</param>
                public static string DesDecryptFixKey(string p_strInput,string key)
                {
                    byte[] byKey = null;
                    byte[] IV = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
                    byte[] inputByteArray = new Byte[p_strInput.Length];
                    try
                    {
                        byKey = System.Text.Encoding.UTF8.GetBytes(key.Substring(0, 8));
                        DESCryptoServiceProvider des = new DESCryptoServiceProvider();
                        des.Mode = CipherMode.ECB;
                        inputByteArray = Convert.FromBase64String(p_strInput);
                        MemoryStream ms = new MemoryStream();
                        CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(byKey, IV), CryptoStreamMode.Write);
                        cs.Write(inputByteArray, 0, inputByteArray.Length);
                        cs.FlushFinalBlock();
                        System.Text.Encoding encoding = new System.Text.UTF8Encoding();
                        return encoding.GetString(ms.ToArray());
                    }
                    catch (System.Exception ex)
                    {
                        throw (ex);
                    }
                }
                #endregion
                 
                #region DES加密字符串
                ///// <summary>
                /////
                ///// 注意:密钥必须为8位
                ///// </summary>
                /// <summary>
                /// 加密字符串,使用内部默认秘钥
                /// </summary>
                /// <param name="p_strInput">明码</param>
                /// <returns>加密后的密码</returns>
                public static string DesEncryptFixKey(string p_strInput)
                {
                    return DesEncryptFixKey(p_strInput,inlineKey);
                }
                #endregion
                 
                #region DES解密字符串
                //const string m_strEncryptKey = "kinghuns"; zh注释
                /// <summary>
                /// 解密字符串,使用内部默认秘钥
                /// </summary>
                /// <param name="this.inputString">加了密的字符串</param>
                /// <param name="decryptKey">密钥</param>
                public static string DesDecryptFixKey(string p_strInput)
                {
                    return DesDecryptFixKey(p_strInput,inlineKey);
                }
                #endregion
      
                public static String md5(String s)
                {
                    MD5 md5 = new MD5CryptoServiceProvider();
                    byte[] bytes = System.Text.Encoding.UTF8.GetBytes(s);
                    bytes = md5.ComputeHash(bytes);
                    md5.Clear();
                    string ret = "";
                    for (int i = 0; i < bytes.Length; i++)
                    {
                        ret += Convert.ToString(bytes[i], 16).PadLeft(2, '0');
                    }
                    return ret.PadLeft(32, '0');
                }
            }
    }
    

    jni层实现

    参考:Android 平台更加安全的DES加密方式

    最后

    对于跨平台联合开发,记得除了在自己这个平台验证外,一定要在其他平台也做相应的验证,不要盲目自信。

    相关文章

      网友评论

          本文标题:各个平台DES加密方式的实现

          本文链接:https://www.haomeiwen.com/subject/canwlctx.html