精华内容
下载资源
问答
  • 3DES加密

    2021-01-12 14:32:32
    3DES加密 /** * 3DES加密 * * @param data 普通文本 * @param desKey 密码 * @return * @throws Exception */ public static String des3EncodeECB(String desKey, String data) { Security.addProvider...

    3DES加密

      /**
         * 3DES加密
         *
         * @param data   普通文本
         * @param desKey 密码
         * @return
         * @throws Exception
         */
        public static String des3EncodeECB(String desKey, String data) {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            try {
                byte[] dataByte = data.getBytes(StandardCharsets.UTF_8);
                byte[] key = build3DesKey(desKey);
                //生成密钥
                SecretKey deSede = new SecretKeySpec(key, "DESede");
                Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS7Padding");
                cipher.init(Cipher.ENCRYPT_MODE, deSede);
                return new BASE64Encoder().encode(cipher.doFinal(dataByte));
            } catch (Exception e) {
                e.printStackTrace();
                return StringUtils.EMPTY;
            }
        }

    3DES解密

        /**
         * 3DES解密
         *
         * @param data   加密文本
         * @param desKey 密码
         * @return
         */
        public static String des3DecodeECB(String desKey, String data) {
            try {
                //--通过base64,将字符串转成byte数组
                BASE64Decoder decoder = new BASE64Decoder();
                byte[] dataByte = decoder.decodeBuffer(data);
                byte[] key = build3DesKey(desKey);
                //生成密钥
                SecretKey deSede = new SecretKeySpec(key, "DESede");
                Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS7Padding");
                cipher.init(Cipher.DECRYPT_MODE, deSede);
                byte[] bout = cipher.doFinal(dataByte);
                return new String(bout, StandardCharsets.UTF_8);
            } catch (Exception e) {
                e.printStackTrace();
                return StringUtils.EMPTY;
            }
        }
       /**
         * 根据字符串生成密钥字节数组
         *
         * @param keyStr 密钥字符串
         */
        private static byte[] build3DesKey(String keyStr) {
            try {
                //声明一个24位的字节数组,默认里面都是0
                byte[] key = new byte[24];
                //将字符串转成字节数组
                byte[] temp = keyStr.getBytes(StandardCharsets.UTF_8);
                if (key.length > temp.length) {
                    //如果temp不够24位,则拷贝temp数组整个长度的内容到key数组中
                    System.arraycopy(temp, 0, key, 0, temp.length);
                } else {
                    //如果temp大于24位,则拷贝temp数组24个长度的内容到key数组中
                    System.arraycopy(temp, 0, key, 0, key.length);
                }
                return key;
            } catch (Exception e) {
                e.printStackTrace();
                return null;
            }
        }

     

    展开全文
  • 3DES 加密

    2019-09-20 10:25:27
    今天介绍下对称加密的3DES加密3des加密是比较安全的对称加密算法,是3层des加密后的算法。 双方约定好相同的key,以及偏移量iv,加密模式,填充,然后进行加解密。 只有4个变量都相同才能加解密一致,所以安全...

      今天介绍下对称加密的3DES加密。

    3des加密是比较安全的对称加密算法,是3层des加密后的算法。

    双方约定好相同的key,以及偏移量iv,加密模式,填充,然后进行加解密。

    只有4个变量都相同才能加解密一致,所以安全上来说是比较安全的。

    1.加密模式包含:

    EBC、CBC、CTR、OFB、CFB

    2.填充包含:

    pcks5padding、pcks7padding 、zeropadding、iso10126、ansix923

    3 key和iv  双方约定就好了。

    以下是js的3des加密:

    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
      <title>3des加解密</title>
      <meta charset="utf-8">
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
      <script type="text/javascript" src="3DES.js"></script>
    </head>
    <body>
    <script type="text/javascript">
    var str = "15629551180";
    document.write("原字符串:</br>"+str);
    var key = "sdghjsdhgjhsdkjghioewiouew234231";         
    //alert(decrypt_3des);
    var des3en = DES3.encrypt(key,str);
    document.write("</br>des3加密后:</br>"+des3en);
    document.write("</br>des3解密后:</br>"+DES3.decrypt(key,des3en));
    </script>
    </body>

    3DES.js

    /** 
     * DES 加密算法 
     * 
     * 该函数接受一个 8 字节字符串作为普通 DES 算法的密钥(也就是 64 位,但是算法只使用 56 位),或者接受一个 24 字节字符串作为 3DES 
     * 算法的密钥;第二个参数是要加密或解密的信息字符串;第三个布尔值参数用来说明信息是加密还是解密;接下来的可选参数 mode 如果是 0 表示 ECB 
     * 模式,1 表示 CBC 模式,默认是 ECB 模式;最后一个可选项是一个 8 字节的输入向量字符串(在 ECB 模式下不使用)。返回的密文是字符串。 
     * 
     * 参数: <br> 
     * key: 8字节字符串作为普通 DES 算法的密钥,或 24 字节字符串作为 3DES <br> 
     * message: 加密或解密的信息字符串<br> 
     * encrypt: 布尔值参数用来说明信息是加密还是解密<br> 
     * mode: 1:CBC模式,0:ECB模式(默认)<br> 
     * iv:<br> 
     * padding: 可选项, 8字节的输入向量字符串(在 ECB 模式下不使用) 
     */
    //this takes the key, the message, and whether to encrypt or decrypt
    function des (key, message, encrypt, mode, iv, padding) {
      if(encrypt) //如果是加密的话,首先转换编码
        message = unescape(encodeURIComponent(message));
      //declaring this locally speeds things up a bit
      var spfunction1 = new Array (0x1010400,0,0x10000,0x1010404,0x1010004,0x10404,0x4,0x10000,0x400,0x1010400,0x1010404,0x400,0x1000404,0x1010004,0x1000000,0x4,0x404,0x1000400,0x1000400,0x10400,0x10400,0x1010000,0x1010000,0x1000404,0x10004,0x1000004,0x1000004,0x10004,0,0x404,0x10404,0x1000000,0x10000,0x1010404,0x4,0x1010000,0x1010400,0x1000000,0x1000000,0x400,0x1010004,0x10000,0x10400,0x1000004,0x400,0x4,0x1000404,0x10404,0x1010404,0x10004,0x1010000,0x1000404,0x1000004,0x404,0x10404,0x1010400,0x404,0x1000400,0x1000400,0,0x10004,0x10400,0,0x1010004);
      var spfunction2 = new Array (-0x7fef7fe0,-0x7fff8000,0x8000,0x108020,0x100000,0x20,-0x7fefffe0,-0x7fff7fe0,-0x7fffffe0,-0x7fef7fe0,-0x7fef8000,-0x80000000,-0x7fff8000,0x100000,0x20,-0x7fefffe0,0x108000,0x100020,-0x7fff7fe0,0,-0x80000000,0x8000,0x108020,-0x7ff00000,0x100020,-0x7fffffe0,0,0x108000,0x8020,-0x7fef8000,-0x7ff00000,0x8020,0,0x108020,-0x7fefffe0,0x100000,-0x7fff7fe0,-0x7ff00000,-0x7fef8000,0x8000,-0x7ff00000,-0x7fff8000,0x20,-0x7fef7fe0,0x108020,0x20,0x8000,-0x80000000,0x8020,-0x7fef8000,0x100000,-0x7fffffe0,0x100020,-0x7fff7fe0,-0x7fffffe0,0x100020,0x108000,0,-0x7fff8000,0x8020,-0x80000000,-0x7fefffe0,-0x7fef7fe0,0x108000);
      var spfunction3 = new Array (0x208,0x8020200,0,0x8020008,0x8000200,0,0x20208,0x8000200,0x20008,0x8000008,0x8000008,0x20000,0x8020208,0x20008,0x8020000,0x208,0x8000000,0x8,0x8020200,0x200,0x20200,0x8020000,0x8020008,0x20208,0x8000208,0x20200,0x20000,0x8000208,0x8,0x8020208,0x200,0x8000000,0x8020200,0x8000000,0x20008,0x208,0x20000,0x8020200,0x8000200,0,0x200,0x20008,0x8020208,0x8000200,0x8000008,0x200,0,0x8020008,0x8000208,0x20000,0x8000000,0x8020208,0x8,0x20208,0x20200,0x8000008,0x8020000,0x8000208,0x208,0x8020000,0x20208,0x8,0x8020008,0x20200);
      var spfunction4 = new Array (0x802001,0x2081,0x2081,0x80,0x802080,0x800081,0x800001,0x2001,0,0x802000,0x802000,0x802081,0x81,0,0x800080,0x800001,0x1,0x2000,0x800000,0x802001,0x80,0x800000,0x2001,0x2080,0x800081,0x1,0x2080,0x800080,0x2000,0x802080,0x802081,0x81,0x800080,0x800001,0x802000,0x802081,0x81,0,0,0x802000,0x2080,0x800080,0x800081,0x1,0x802001,0x2081,0x2081,0x80,0x802081,0x81,0x1,0x2000,0x800001,0x2001,0x802080,0x800081,0x2001,0x2080,0x800000,0x802001,0x80,0x800000,0x2000,0x802080);
      var spfunction5 = new Array (0x100,0x2080100,0x2080000,0x42000100,0x80000,0x100,0x40000000,0x2080000,0x40080100,0x80000,0x2000100,0x40080100,0x42000100,0x42080000,0x80100,0x40000000,0x2000000,0x40080000,0x40080000,0,0x40000100,0x42080100,0x42080100,0x2000100,0x42080000,0x40000100,0,0x42000000,0x2080100,0x2000000,0x42000000,0x80100,0x80000,0x42000100,0x100,0x2000000,0x40000000,0x2080000,0x42000100,0x40080100,0x2000100,0x40000000,0x42080000,0x2080100,0x40080100,0x100,0x2000000,0x42080000,0x42080100,0x80100,0x42000000,0x42080100,0x2080000,0,0x40080000,0x42000000,0x80100,0x2000100,0x40000100,0x80000,0,0x40080000,0x2080100,0x40000100);
      var spfunction6 = new Array (0x20000010,0x20400000,0x4000,0x20404010,0x20400000,0x10,0x20404010,0x400000,0x20004000,0x404010,0x400000,0x20000010,0x400010,0x20004000,0x20000000,0x4010,0,0x400010,0x20004010,0x4000,0x404000,0x20004010,0x10,0x20400010,0x20400010,0,0x404010,0x20404000,0x4010,0x404000,0x20404000,0x20000000,0x20004000,0x10,0x20400010,0x404000,0x20404010,0x400000,0x4010,0x20000010,0x400000,0x20004000,0x20000000,0x4010,0x20000010,0x20404010,0x404000,0x20400000,0x404010,0x20404000,0,0x20400010,0x10,0x4000,0x20400000,0x404010,0x4000,0x400010,0x20004010,0,0x20404000,0x20000000,0x400010,0x20004010);
      var spfunction7 = new Array (0x200000,0x4200002,0x4000802,0,0x800,0x4000802,0x200802,0x4200800,0x4200802,0x200000,0,0x4000002,0x2,0x4000000,0x4200002,0x802,0x4000800,0x200802,0x200002,0x4000800,0x4000002,0x4200000,0x4200800,0x200002,0x4200000,0x800,0x802,0x4200802,0x200800,0x2,0x4000000,0x200800,0x4000000,0x200800,0x200000,0x4000802,0x4000802,0x4200002,0x4200002,0x2,0x200002,0x4000000,0x4000800,0x200000,0x4200800,0x802,0x200802,0x4200800,0x802,0x4000002,0x4200802,0x4200000,0x200800,0,0x2,0x4200802,0,0x200802,0x4200000,0x800,0x4000002,0x4000800,0x800,0x200002);
      var spfunction8 = new Array (0x10001040,0x1000,0x40000,0x10041040,0x10000000,0x10001040,0x40,0x10000000,0x40040,0x10040000,0x10041040,0x41000,0x10041000,0x41040,0x1000,0x40,0x10040000,0x10000040,0x10001000,0x1040,0x41000,0x40040,0x10040040,0x10041000,0x1040,0,0,0x10040040,0x10000040,0x10001000,0x41040,0x40000,0x41040,0x40000,0x10041000,0x1000,0x40,0x10040040,0x1000,0x41040,0x10001000,0x40,0x10000040,0x10040000,0x10040040,0x10000000,0x40000,0x10001040,0,0x10041040,0x40040,0x10000040,0x10040000,0x10001000,0x10001040,0,0x10041040,0x41000,0x41000,0x1040,0x1040,0x40040,0x10000000,0x10041000);
      //create the 16 or 48 subkeys we will need
      var keys = des_createKeys (key);
      var m=0, i, j, temp, temp2, right1, right2, left, right, looping;
      var cbcleft, cbcleft2, cbcright, cbcright2
      var endloop, loopinc;
      var len = message.length;
      var chunk = 0;
      //set up the loops for single and triple des
      var iterations = keys.length == 32 ? 3 : 9; //single or triple des
      if (iterations == 3) {looping = encrypt ? new Array (0, 32, 2) : new Array (30, -2, -2);}
      else {looping = encrypt ? new Array (0, 32, 2, 62, 30, -2, 64, 96, 2) : new Array (94, 62, -2, 32, 64, 2, 30, -2, -2);}
      //pad the message depending on the padding parameter
      if (padding == 2) message += "    "; //pad the message with spaces
      else if (padding == 1) {
        if(encrypt) {
          temp = 8-(len%8);
          message += String.fromCharCode(temp,temp,temp,temp,temp,temp,temp,temp);
          if (temp===8) len+=8;
        }
      } //PKCS7 padding
      else if (!padding) message += "\0\0\0\0\0\0\0\0"; //pad the message out with null bytes
      //store the result here
      var result = "";
      var tempresult = "";
      if (mode == 1) { //CBC mode
        cbcleft = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
        cbcright = (iv.charCodeAt(m++) << 24) | (iv.charCodeAt(m++) << 16) | (iv.charCodeAt(m++) << 8) | iv.charCodeAt(m++);
        m=0;
      }
      //loop through each 64 bit chunk of the message
      while (m < len) {
        left = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++);
        right = (message.charCodeAt(m++) << 24) | (message.charCodeAt(m++) << 16) | (message.charCodeAt(m++) << 8) | message.charCodeAt(m++);
        //for Cipher Block Chaining mode, xor the message with the previous result
        if (mode == 1) {if (encrypt) {left ^= cbcleft; right ^= cbcright;} else {cbcleft2 = cbcleft; cbcright2 = cbcright; cbcleft = left; cbcright = right;}}
        //first each 64 but chunk of the message must be permuted according to IP
        temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);
        temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16);
        temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2);
        temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);
        temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
        left = ((left << 1) | (left >>> 31));
        right = ((right << 1) | (right >>> 31));
        //do this either 1 or 3 times for each chunk of the message
        for (j=0; j<iterations; j+=3) {
          endloop = looping[j+1];
          loopinc = looping[j+2];
          //now go through and perform the encryption or decryption
          for (i=looping[j]; i!=endloop; i+=loopinc) { //for efficiency
            right1 = right ^ keys[i];
            right2 = ((right >>> 4) | (right << 28)) ^ keys[i+1];
            //the result is attained by passing these bytes through the S selection functions
            temp = left;
            left = right;
            right = temp ^ (spfunction2[(right1 >>> 24) & 0x3f] | spfunction4[(right1 >>> 16) & 0x3f]
              | spfunction6[(right1 >>> 8) & 0x3f] | spfunction8[right1 & 0x3f]
              | spfunction1[(right2 >>> 24) & 0x3f] | spfunction3[(right2 >>> 16) & 0x3f]
              | spfunction5[(right2 >>> 8) & 0x3f] | spfunction7[right2 & 0x3f]);
          }
          temp = left; left = right; right = temp; //unreverse left and right
        } //for either 1 or 3 iterations
        //move then each one bit to the right
        left = ((left >>> 1) | (left << 31));
        right = ((right >>> 1) | (right << 31));
        //now perform IP-1, which is IP in the opposite direction
        temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
        temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);
        temp = ((right >>> 2) ^ left) & 0x33333333; left ^= temp; right ^= (temp << 2);
        temp = ((left >>> 16) ^ right) & 0x0000ffff; right ^= temp; left ^= (temp << 16);
        temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);
        //for Cipher Block Chaining mode, xor the message with the previous result
        if (mode == 1) {if (encrypt) {cbcleft = left; cbcright = right;} else {left ^= cbcleft2; right ^= cbcright2;}}
        tempresult += String.fromCharCode ((left>>>24), ((left>>>16) & 0xff), ((left>>>8) & 0xff), (left & 0xff), (right>>>24), ((right>>>16) & 0xff), ((right>>>8) & 0xff), (right & 0xff));
        chunk += 8;
        if (chunk == 512) {result += tempresult; tempresult = ""; chunk = 0;}
      } //for every 8 characters, or 64 bits in the message
      //return the result as an array
      result += tempresult;
      result = result.replace(/\0*$/g, "");
      if(!encrypt ) { //如果是解密的话,解密结束后对PKCS7 padding进行解码,并转换成utf-8编码
        if(padding === 1) { //PKCS7 padding解码
          var len = result.length, paddingChars = 0;
          len && (paddingChars = result.charCodeAt(len-1));
          (paddingChars <= 8) && (result = result.substring(0, len - paddingChars));
        }
        //转换成UTF-8编码
        result = decodeURIComponent(escape(result));
      }
      return result;
    } //end of des
    //des_createKeys
    //this takes as input a 64 bit key (even though only 56 bits are used)
    //as an array of 2 integers, and returns 16 48 bit keys
    function des_createKeys (key) {
      //declaring this locally speeds things up a bit
      var pc2bytes0 = new Array (0,0x4,0x20000000,0x20000004,0x10000,0x10004,0x20010000,0x20010004,0x200,0x204,0x20000200,0x20000204,0x10200,0x10204,0x20010200,0x20010204);
      var pc2bytes1 = new Array (0,0x1,0x100000,0x100001,0x4000000,0x4000001,0x4100000,0x4100001,0x100,0x101,0x100100,0x100101,0x4000100,0x4000101,0x4100100,0x4100101);
      var pc2bytes2 = new Array (0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808,0,0x8,0x800,0x808,0x1000000,0x1000008,0x1000800,0x1000808);
      var pc2bytes3 = new Array (0,0x200000,0x8000000,0x8200000,0x2000,0x202000,0x8002000,0x8202000,0x20000,0x220000,0x8020000,0x8220000,0x22000,0x222000,0x8022000,0x8222000);
      var pc2bytes4 = new Array (0,0x40000,0x10,0x40010,0,0x40000,0x10,0x40010,0x1000,0x41000,0x1010,0x41010,0x1000,0x41000,0x1010,0x41010);
      var pc2bytes5 = new Array (0,0x400,0x20,0x420,0,0x400,0x20,0x420,0x2000000,0x2000400,0x2000020,0x2000420,0x2000000,0x2000400,0x2000020,0x2000420);
      var pc2bytes6 = new Array (0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002,0,0x10000000,0x80000,0x10080000,0x2,0x10000002,0x80002,0x10080002);
      var pc2bytes7 = new Array (0,0x10000,0x800,0x10800,0x20000000,0x20010000,0x20000800,0x20010800,0x20000,0x30000,0x20800,0x30800,0x20020000,0x20030000,0x20020800,0x20030800);
      var pc2bytes8 = new Array (0,0x40000,0,0x40000,0x2,0x40002,0x2,0x40002,0x2000000,0x2040000,0x2000000,0x2040000,0x2000002,0x2040002,0x2000002,0x2040002);
      var pc2bytes9 = new Array (0,0x10000000,0x8,0x10000008,0,0x10000000,0x8,0x10000008,0x400,0x10000400,0x408,0x10000408,0x400,0x10000400,0x408,0x10000408);
      var pc2bytes10 = new Array (0,0x20,0,0x20,0x100000,0x100020,0x100000,0x100020,0x2000,0x2020,0x2000,0x2020,0x102000,0x102020,0x102000,0x102020);
      var pc2bytes11 = new Array (0,0x1000000,0x200,0x1000200,0x200000,0x1200000,0x200200,0x1200200,0x4000000,0x5000000,0x4000200,0x5000200,0x4200000,0x5200000,0x4200200,0x5200200);
      var pc2bytes12 = new Array (0,0x1000,0x8000000,0x8001000,0x80000,0x81000,0x8080000,0x8081000,0x10,0x1010,0x8000010,0x8001010,0x80010,0x81010,0x8080010,0x8081010);
      var pc2bytes13 = new Array (0,0x4,0x100,0x104,0,0x4,0x100,0x104,0x1,0x5,0x101,0x105,0x1,0x5,0x101,0x105);
      //how many iterations (1 for des, 3 for triple des)
      var iterations = key.length > 8 ? 3 : 1; //changed by Paul 16/6/2007 to use Triple DES for 9+ byte keys
      //stores the return keys
      var keys = new Array (32 * iterations);
      //now define the left shifts which need to be done
      var shifts = new Array (0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0);
      //other variables
      var lefttemp, righttemp, m=0, n=0, temp;
      for (var j=0; j<iterations; j++) { //either 1 or 3 iterations
        var left = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++);
        var right = (key.charCodeAt(m++) << 24) | (key.charCodeAt(m++) << 16) | (key.charCodeAt(m++) << 8) | key.charCodeAt(m++);
        temp = ((left >>> 4) ^ right) & 0x0f0f0f0f; right ^= temp; left ^= (temp << 4);
        temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16);
        temp = ((left >>> 2) ^ right) & 0x33333333; right ^= temp; left ^= (temp << 2);
        temp = ((right >>> -16) ^ left) & 0x0000ffff; left ^= temp; right ^= (temp << -16);
        temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
        temp = ((right >>> 8) ^ left) & 0x00ff00ff; left ^= temp; right ^= (temp << 8);
        temp = ((left >>> 1) ^ right) & 0x55555555; right ^= temp; left ^= (temp << 1);
        //the right side needs to be shifted and to get the last four bits of the left side
        temp = (left << 8) | ((right >>> 20) & 0x000000f0);
        //left needs to be put upside down
        left = (right << 24) | ((right << 8) & 0xff0000) | ((right >>> 8) & 0xff00) | ((right >>> 24) & 0xf0);
        right = temp;
        //now go through and perform these shifts on the left and right keys
        for (var i=0; i < shifts.length; i++) {
          //shift the keys either one or two bits to the left
          if (shifts[i]) {left = (left << 2) | (left >>> 26); right = (right << 2) | (right >>> 26);}
          else {left = (left << 1) | (left >>> 27); right = (right << 1) | (right >>> 27);}
          left &= -0xf; right &= -0xf;
          //now apply PC-2, in such a way that E is easier when encrypting or decrypting
          //this conversion will look like PC-2 except only the last 6 bits of each byte are used
          //rather than 48 consecutive bits and the order of lines will be according to
          //how the S selection functions will be applied: S2, S4, S6, S8, S1, S3, S5, S7
          lefttemp = pc2bytes0[left >>> 28] | pc2bytes1[(left >>> 24) & 0xf]
            | pc2bytes2[(left >>> 20) & 0xf] | pc2bytes3[(left >>> 16) & 0xf]
            | pc2bytes4[(left >>> 12) & 0xf] | pc2bytes5[(left >>> 8) & 0xf]
            | pc2bytes6[(left >>> 4) & 0xf];
          righttemp = pc2bytes7[right >>> 28] | pc2bytes8[(right >>> 24) & 0xf]
            | pc2bytes9[(right >>> 20) & 0xf] | pc2bytes10[(right >>> 16) & 0xf]
            | pc2bytes11[(right >>> 12) & 0xf] | pc2bytes12[(right >>> 8) & 0xf]
            | pc2bytes13[(right >>> 4) & 0xf];
          temp = ((righttemp >>> 16) ^ lefttemp) & 0x0000ffff;
          keys[n++] = lefttemp ^ temp; keys[n++] = righttemp ^ (temp << 16);
        }
      } //for each iterations
      //return the keys we've created
      return keys;
    } //end of des_createKeys
    function genkey(key, start, end) {
      //8 byte / 64 bit Key (DES) or 192 bit Key
      return {key:pad(key.slice(start, end)),vector: 1};
    }
    function pad(key) {
      for (var i = key.length; i<24; i++) {
        key+="0";
      }
      return key;
    }
    var des3iv = '12345678';
    var DES3 = {
      //3DES加密,CBC/PKCS5Padding
      encrypt:function(key,input){
        var genKey = genkey(key, 0, 24);
        return btoa(des(genKey.key, input, 1, 1, des3iv, 1));
      },
      3DES解密,CBC/PKCS5Padding
      decrypt:function(key,input){
        var genKey = genkey(key, 0, 24); 
        return des(genKey.key, atob(input), 0, 1, des3iv, 1); 
      }
    };
    

     

    展开全文
  • 3Des加密

    千次阅读 2019-01-03 11:00:23
    使用3Des加密算法前,我们需要了解一下当前主流的加密模式:单向加密和双向加密,两者最大的区别在于加密的密文是否具有可逆性。  单向加密:将需要加密的数据进行加密,并且密文不可进行解密,像我们常用的加密...

           使用3Des加密算法前,我们需要了解一下当前主流的加密模式:单向加密和双向加密,两者最大的区别在于加密的密文是否具有可逆性。

           单向加密:将需要加密的数据进行加密,并且密文不可进行解密,像我们常用的加密算法MD5就属于这种。

           双向加密:和单向加密不同的是可以通过某些方式进行加解密的操作,其中分为对称加密和非对称加密。

                   对称加密:指数据使用者必须拥有相同的密钥才可以进行加密解密,就像彼此约定的一串暗号,本文介绍的3Des加密就属于这种。

                   非对称加密:通过一组包含公钥和私钥的密码来加密解密,用公钥加密,私钥解密,首推的就是RSA加密

    ---------------------------------------------------------------------------------------------------------------------------------------

             3Des加密算法,由于可以逆推原文,所以主要通过本地的唯一密钥来保证数据的安全性,我这边通过生成随机的256位加密字符串存储在本地,代码读取时将其通过md5加密成32位的字符串(由于本地有原始密钥,不必担心md5加密不可逆),最后以这32位加密字符串作为密钥进行加解密的操作。

      

    package com.youfuli.util;
    
    
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory;
    import javax.crypto.spec.DESKeySpec;
    import javax.crypto.spec.DESedeKeySpec;
    import javax.crypto.spec.IvParameterSpec;
    
    import Decoder.BASE64Decoder;
    import Decoder.BASE64Encoder;
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStreamReader;
    import java.util.UUID;
    
    /**
     * Created by lixiaotian on 2018/12/25.
     */
    public class Des3Util {
    
    	private static final String IV = "1234567-";
    
    	/**
    	 * DESCBC加密
    	 *
    	 * @param src 数据源
    	 * @param key 密钥,长度必须是8的倍数
    	 * @return 返回加密后的数据
    	 * @throws Exception
    	 */
    	public String encryptDESCBC(final String src, final String key) throws Exception {
    
    		// --生成key,同时制定是des还是DESede,两者的key长度要求不同
    		final DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
    		final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
    		final SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
    
    		// --加密向量
    		final IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8"));
    
    		// --通过Chipher执行加密得到的是一个byte的数组,Cipher.getInstance("DES")就是采用ECB模式,cipher.init(Cipher.ENCRYPT_MODE,
    		// secretKey)就可以了.
    		final Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
    		cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
    		final byte[] b = cipher.doFinal(src.getBytes("UTF-8"));
    
    		// --通过base64,将加密数组转换成字符串
    		final BASE64Encoder encoder = new BASE64Encoder();
    		return encoder.encode(b);
    	}
    
    	/**
    	 * DESCBC解密
    	 *
    	 * @param src 数据源
    	 * @param key 密钥,长度必须是8的倍数
    	 * @return 返回解密后的原始数据
    	 * @throws Exception
    	 */
    	public String decryptDESCBC(final String src, final String key) throws Exception {
    		// --通过base64,将字符串转成byte数组
    		final BASE64Decoder decoder = new BASE64Decoder();
    		final byte[] bytesrc = decoder.decodeBuffer(src);
    
    		// --解密的key
    		final DESKeySpec desKeySpec = new DESKeySpec(key.getBytes("UTF-8"));
    		final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
    		final SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
    
    		// --向量
    		final IvParameterSpec iv = new IvParameterSpec(IV.getBytes("UTF-8"));
    
    		// --Chipher对象解密Cipher.getInstance("DES")就是采用ECB模式,cipher.init(Cipher.DECRYPT_MODE,
    		// secretKey)就可以了.
    		final Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
    		cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
    		final byte[] retByte = cipher.doFinal(bytesrc);
    
    		return new String(retByte);
    
    	}
    
    	// 3DESECB加密,key必须是长度大于等于 3*8 = 24 位哈
    	public static String encryptThreeDESECB(final String src, final String key) throws Exception {
    		final DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));
    		final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
    		final SecretKey securekey = keyFactory.generateSecret(dks);
    
    		final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    		cipher.init(Cipher.ENCRYPT_MODE, securekey);
    		final byte[] b = cipher.doFinal(src.getBytes());
    
    		final BASE64Encoder encoder = new BASE64Encoder();
    		return encoder.encode(b).replaceAll("\r", "").replaceAll("\n", "");
    
    	}
    
    	// 3DESECB解密,key必须是长度大于等于 3*8 = 24 位哈
    	public static String decryptThreeDESECB(final String src, final String key) throws Exception {
    		// --通过base64,将字符串转成byte数组
    		final BASE64Decoder decoder = new BASE64Decoder();
    		final byte[] bytesrc = decoder.decodeBuffer(src);
    		// --解密的key
    		final DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));
    		final SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
    		final SecretKey securekey = keyFactory.generateSecret(dks);
    
    		// --Chipher对象解密
    		final Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    		cipher.init(Cipher.DECRYPT_MODE, securekey);
    		final byte[] retByte = cipher.doFinal(bytesrc);
    
    		return new String(retByte);
    	}
    }
    

           此处提供的代码中,展现了des加解密和3des加解密的相应的方法。des和3Des加密算法的区别在于des加密算法的实际密文长度为56位,导致加密长度不足,才会出现3Des加密算法来进行弥补的,通过执行3次DES来达到增加密钥长度和安全的目的。

            这边我提供一个测试类,用于测试生成本地唯一密钥文件和md5加密本地密钥文件,然后采用3Des对需要加解密的数据进行加解密的操作。

            

    public static void main(String[] args) throws Exception {
    		String str2 = "";
    		StringBuilder result = new StringBuilder();
    		File newfile = new File("D:/decrypt");
    		if (!newfile.exists()) {
    			newfile.mkdirs();
    			File file = new File("D:/decrypt"+"/decrypt.txt");
    			if(!file.exists()) {
    				file.createNewFile();
    			}
    			for (int i=0;i<8;i++) {
    				UUID uuid = UUID.randomUUID();
    	            String str = uuid.toString();
    	            String str1 = str.substring(0, 8) + str.substring(9, 13) + str.substring(14, 18) + str.substring(19, 23) + str.substring(24);
    	            str2 = str2+str1;
    			}
    			FileOutputStream fileOutputStream = null;
    			fileOutputStream = new FileOutputStream(file);
                fileOutputStream.write(str2.getBytes("UTF-8"));
                fileOutputStream.close();
    		}
    		BufferedReader bfr = new BufferedReader(new InputStreamReader(new FileInputStream("D:/decrypt/decrypt.txt"), "UTF-8"));
    
    		String lineTxt = null;
    		while ((lineTxt = bfr.readLine()) != null) {
    			result.append(lineTxt).append("\n");
    		}
    		bfr.close();
    		str2 = result.toString();
    		System.out.println(str2);
    		String md5Key = md5.getMD5Str(str2);
    		System.out.println("密钥:"+md5Key);
    		String keys = "654321";
    		Des3Util des3 = new Des3Util();
    		String txt = des3.encryptThreeDESECB(keys, md5Key);
    		System.out.println("加密数据:"+txt);
    		String decy = des3.decryptThreeDESECB(txt,md5Key);
    		System.out.println("解密数据:"+decy);
    	}

         可以看出,我本地通过uuid循环八次随机生成密钥文件,然后对其进行md5,最后调用相应的方法进行加解密的操作,最后对需要加密的数据“654321”的加解密的操作结果如下:

      

    第一行:打印出本地长度为256位的原始密钥

    第二行:打印出使用md5加密后的密钥

    第三行:对654321进行加密后的加密数据

    第四行:对加密数据preJaIoIzLw=进行解密,最后还原为明文654321

    ---------------------------------------------------------------------------------------------------------------------------------------

          此次采用3Des加密算法,在于把本地配置文件中的密码配置进行加密化操作,将配置文件中的密码加密保存在数据库中,然后再读取时配置在缓存中。

    package com.youfuli.util;
    
    import com.youfuli.dao.FlxThirdAccountInfoMapper;
    import com.youfuli.entity.FlxThirdAccountInfo;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.util.CollectionUtils;
    
    import java.io.*;
    import java.util.*;
    
    /**
     * Created by lixiaotian on 2018/12/25.
     */
    public class ThirdAccountMap {
    
        private static Logger logger = LoggerFactory.getLogger(ThirdAccountMap.class);
    
        //账户map
        private static Map<String, String> accMap;
    
        static FlxThirdAccountInfoMapper thirdAccountInfoMapper = SpringUtil.getBean(FlxThirdAccountInfoMapper.class);
    
        static {
            try {
                List<FlxThirdAccountInfo> thirdAccountInfos = thirdAccountInfoMapper.findAccount();
                if (CollectionUtils.isEmpty(thirdAccountInfos)) {
                    logger.info("数据库还未导入加密密码");
                }
                Properties prop = PropertiesUtil.getInstance();
                String decryptUrl = prop.getProperty("decrypt.url");
                StringBuilder result = new StringBuilder();
                File newfile = new File(decryptUrl);
                String txtFile = decryptUrl + "/decrypt.txt";
                File file = new File(txtFile);
                //文件不存在的情况
                if (!file.exists()) {
                    if (!newfile.exists()) {
                        newfile.mkdirs();
                    }
                    file.createNewFile();
                    String str2 = "";
                    for (int i = 0; i < 8; i++) {
                        UUID uuid = UUID.randomUUID();
                        String str = uuid.toString();
                        String str1 = str.substring(0, 8) + str.substring(9, 13) + str.substring(14, 18) + str.substring(19, 23) + str.substring(24);
                        str2 = str2 + str1;
                    }
                    FileOutputStream fileOutputStream = null;
                    fileOutputStream = new FileOutputStream(file);
                    fileOutputStream.write(str2.getBytes("UTF-8"));
                    fileOutputStream.close();
                }
                BufferedReader bfr = new BufferedReader(new InputStreamReader(new FileInputStream(new File(txtFile)), "UTF-8"));
                String lineTxt = null;
                while ((lineTxt = bfr.readLine()) != null) {
                    result.append(lineTxt).append("\n");
                }
                bfr.close();
                String str = md5.getMD5Str(result.toString());
                accMap = new HashMap<>();
                for (int i = 0; i < thirdAccountInfos.size(); i++) {
                    String keys = thirdAccountInfos.get(i).getAccountKey();
                    String values = thirdAccountInfos.get(i).getAccountValue();
                    if ("1".equals(thirdAccountInfos.get(i).getIsEncrypt())) {
                        accMap.put(keys, Des3Util.decryptThreeDESECB(values, str));
                    } else {
                        accMap.put(keys, values);
                    }
    
    
                }
                logger.info("数据库解密密码完成");
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    
        /**
         * 根据账户key进行查询
         *
         * @param accountKey
         * @return
         */
        public static String queryThirdKey(String accountKey) {
            if (accMap == null) {
                logger.error("数据库加密信息未加载");
                return null;
            }
            return accMap.get(accountKey);
        }
    }
    

    通过数据库中的key匹配key即可。

    appKey = ThirdAccountMap.queryThirdKey("appKey");

    其中还对文件路径下的文件做了处理,如果不存在即进行新建处理,个人觉得还有优化的空间。一起加油哦。

    展开全文
  • 3des加密

    2019-02-25 16:41:00
    因为工作中要用到加密,接口中要求也是用密文传输数据,用到3des加密,就研究了一下。 在网上也找了好多,但是都不可以用,没法正式运行,终于找到一个可以运行的,自己又修改了一下,记录下来,以后还可能会用到...
    因为工作中要用到加密,接口中要求也是用密文传输数据,用到3des加密,就研究了一下。
    
    在网上也找了好多,但是都不可以用,没法正式运行,终于找到一个可以运行的,自己又修改了一下,记录下来,以后还可能会用到。
    
     
    
    下面安装我要调用的接口文实例:
    
    接口要求:先用3DES对数据进行加密,在用BASE64进行加密。即:BASE64(3DES(value))。
    
             3DES加密规则:
    
    模式:ECB
    
    填充模式:PKCS7Padding
    
    数据块大小:8字节(64位)
    
    初始化向量:无
    
    密钥:XXXXXXXXXXXXXXXXX
    
    首先是一个封装好的类文件:
    
    encrypt_class.php//文件名
    
    
    <?php
    class Crypt3Des {
       public $key = "XXXXXXXXXXXXXXXXX";//这个根据实际情况写
       function Crypt3Des($key){
         $this->key=$key;
       }
       function encrypt($input){//数据加密
         $size = mcrypt_get_block_size(MCRYPT_3DES,'ecb');
         $input = $this->pkcs5_pad($input, $size);
         $key = str_pad($this->key,24,'0');
         $td = mcrypt_module_open(MCRYPT_3DES, '', 'ecb', '');
         $iv = @mcrypt_create_iv (mcrypt_enc_get_iv_size($td), MCRYPT_RAND);
         @mcrypt_generic_init($td, $key, $iv);
         $data = mcrypt_generic($td, $input);
         mcrypt_generic_deinit($td);
         mcrypt_module_close($td);
         //$data = base64_encode($this->PaddingPKCS7($data));
         $data = base64_encode($data);
         return $data;
       }
     
       function decrypt($encrypted){//数据解密
         $encrypted = base64_decode($encrypted);
         $key = str_pad($this->key,24,'0');
         $td = mcrypt_module_open(MCRYPT_3DES,'','ecb','');
         $iv = @mcrypt_create_iv(mcrypt_enc_get_iv_size($td),MCRYPT_RAND);
         $ks = mcrypt_enc_get_key_size($td);
         @mcrypt_generic_init($td, $key, $iv);
         $decrypted = mdecrypt_generic($td, $encrypted);
         mcrypt_generic_deinit($td);
         mcrypt_module_close($td);
         $y=$this->pkcs5_unpad($decrypted);
         return $y;
       }
       function pkcs5_pad ($text, $blocksize) {
         $pad = $blocksize - (strlen($text) % $blocksize);
         return $text . str_repeat(chr($pad), $pad);
       }
       function pkcs5_unpad($text){
         $pad = ord($text{strlen($text)-1});
         if ($pad > strlen($text)) {
            return false;
         }
         if (strspn($text, chr($pad), strlen($text) - $pad) != $pad){
            return false;
         }
         return substr($text, 0, -1 * $pad);
       }
     
       function PaddingPKCS7($data) {
         $block_size = mcrypt_get_block_size(MCRYPT_3DES, MCRYPT_MODE_CBC);
         $padding_char = $block_size - (strlen($data) % $block_size);
         $data .= str_repeat(chr($padding_char),$padding_char);
         return $data;
       }
    }
     $rep=new Crypt3Des('123456');//初始化一个对象,并修改默认密钥
     $input="hello world";
     echo "原文:".$input."<br/>";
     $encrypt_card=$rep->encrypt($input);
     echo "加密:".$encrypt_card."<br/>";
     echo "解密:".$rep->decrypt($rep->encrypt($input));
    ?>
    这是一个非常有用的3des加密,在多数情况下可以直接拿来用。
    
    *********************************************************************
    
    
    
    由于PHP使用mcrypt扩展进行3DES加密,填充模式是跟JAVA以及.NET是不一样的,JAVA和.NET填充模式使用的是PKCS7。
    所以PHP端必须自定义一个函数对加密字符串进行PKCS7模式补位填充。
    另外一点就是双方的KEY注意进行base64编码,最后PHP端经过3DES加密后得到的结果也需要进行base64编码。
    实现了上述规则,这个3DES加密类兼容.net 和java。
    
    
    <?php
    class STD3Des
    {
        private $key = "";
        private $iv = "";
     
        /**
         * 构造,传递二个已经进行base64_encode的KEY与IV
         *
         * @param string $key
         * @param string $iv
         */
        function __construct($key, $iv)
        {
            if (empty($key) || empty($iv)) {
                echo 'key and iv is not valid';
                exit();
            }
            $this->key = $key;
            $this->iv = $iv;
        }
     
        /**
         *加密
         * @param <type> $value
         * @return <type>
         */
        public function encrypt($value)
        {
            $td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CBC, '');
            $iv = base64_decode($this->iv);
            $value = $this->PaddingPKCS7($value);
            $key = base64_decode($this->key);
            mcrypt_generic_init($td, $key, $iv);
            $ret = base64_encode(mcrypt_generic($td, $value));
            mcrypt_generic_deinit($td);
            mcrypt_module_close($td);
            return $ret;
        }
     
        /**
         *解密
         * @param <type> $value
         * @return <type>
         */
        public function decrypt($value)
        {
            $td = mcrypt_module_open(MCRYPT_3DES, '', MCRYPT_MODE_CBC, '');
            $iv = base64_decode($this->iv);
            $key = base64_decode($this->key);
            mcrypt_generic_init($td, $key, $iv);
            $ret = trim(mdecrypt_generic($td, base64_decode($value)));
            $ret = $this->UnPaddingPKCS7($ret);
            mcrypt_generic_deinit($td);
            mcrypt_module_close($td);
            return $ret;
        }
     
        private function PaddingPKCS7($data)
        {
            $block_size = mcrypt_get_block_size('tripledes', 'cbc');
            $padding_char = $block_size - (strlen($data) % $block_size);
            $data .= str_repeat(chr($padding_char), $padding_char);
            return $data;
        }
     
        private function UnPaddingPKCS7($text)
        {
            $pad = ord($text{strlen($text) - 1});
            if ($pad > strlen($text)) {
                return false;
            }
            if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
                return false;
            }
            return substr($text, 0, -1 * $pad);
        }
    }
     
    //使用
    include('STD3Des.class.php');
    $key = 'abcdefgh';
    $iv = 'abcdefgh';
    $msg = 'test string';
    $des = new STD3Des(base64_encode($key), base64_encode($iv));
    $rs1 = $des->encrypt($msg);
    echo $rs1 . '<br />';
    $rs2 = $des->decrypt($rs1);
    echo $rs2;
    ?>

     

    转载于:https://www.cnblogs.com/zhangtianle/p/10431720.html

    展开全文
  • 主要介绍了python实现的DES加密算法和3DES加密算法,以实例形式较为详细的分析了DES加密算法和3DES加密算法的原理与实现技巧,需要的朋友可以参考下
  • C# 3Des加密解密

    万次阅读 2019-05-09 10:32:19
    第三方的加密规则约定:加密经过3DES加密后的Base64 编码 最近在对接一个第三方接口,请求参数和响应参数全采用3des加密规则,由于我是用.NET对接的,而第三方是Java开发的,所以两种程序之间采用的算法有一点差异...
  • 3des 加密

    2015-08-20 15:53:13
    加密: ... /*字符串 DESede(3DES) 加密*/ //注:百度代码识别BUG,代码中空格属全角。拷贝代码之后请自行修改。 import java.security.Security; import javax.crypto.Ciph
  • Java使用3DES加密解密的流程①传入共同约定的密钥(keyBytes)以及算法(Algorithm),来构建SecretKey密钥对象SecretKey deskey = new SecretKeySpec(keyBytes, Algorithm);②根据算法实例化Cipher对象。它负责加密/...
  • 包含密码学中分组密码加密的DES加密和3DES加密算法源代码以及编译完成的可执行文件,代码包含详细注释。
  • C# 3DES加密详解

    2020-09-03 15:49:59
    3Des对每个数据块进行了三次的DES加密算法,是DES的一个更安全的变形。比起最初的DES,3DES更为安全。下面我们来看下在C#中的3DES加密方式的使用
  • --layout: blogtitle: '使用Python进行3DES加密-pyDes'date: 2017-06-01 12:11:34categories: blogtags: codeimage: ''lead-text: 'Python利用pyDes进行3DES加密'选择PyDes在进行请求前使用3DES进行加密获取一个加密...
  • 3DES(即Triple DES)是DES向AES过渡的加密算法(1999年,NIST将3-DES指定为过渡的加密标准),加密算法,其具体实现如下:设...3DES加密过程为:C=Ek3(Dk2(Ek1(P)))3DES解密过程为:P=Dk1(EK2(Dk3(C)))import java.sec...
  • 3des,全称为3DESede或TripleDES,中文解释为是三重数据加密,用户可以通过通过对DES算法进行改进,针对每个数据块进行三次DES加密,下面小编为你带来java实现3des加密解密教程!首先我们需要自行安装配置java环境,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,216
精华内容 2,086
关键字:

3des加密