zoukankan      html  css  js  c++  java
  • 微信小程序及各种平台对接常用可逆加密算法aes256

    不同程序之间经常会交换数据,我们经常采用的套路是:

    假设要传输的信息是json,我们假设其为json_data,通过http传递信息为

    json_data_encode=json_data&sign=md5(json_data+key)

    接收方通过验证sign就知道内容有没有被篡改.

    但是,这样json_data作为明码传送会让我们不太开心,所以今天的我们要介绍的aes256出马了,他是一强度很高的可逆加密算法!

    aes256加密出来的内容是二进制的,不好通过http协议传输,所以我们再配合上base64转成ascii码

    加密前,aes256要求字节数必须是32字节的倍数,所以使用pkcs7进行填充可以解决问题..介绍完原理,直接贴代码

    写了3个版本,openresty及python和php的...请查收

    local aes = require 'resty.aes'
     local base64_encode = ngx.encode_base64
     local base64_decode = ngx.decode_base64
     
     local key = "a12e93c9edadeaa47eb1aeabe27dabef"
     local iv = "a12e93c9edadeaa4"
     -- AES 128 CBC with IV and no SALT
     local cipher = aes.cipher(256,"cbc")
     local aes_256_cbc_with_iv = aes:new(key,nil,cipher,{iv=iv})
     
     local function decrypt(input)
         input = base64_decode(input)
         input = aes_256_cbc_with_iv:decrypt(input)
         -- 取最后一个字符的ascii值
         --local padding = string.byte(input,-1)
         --return string.sub(input,-padding)
         return input
     end
     
     local function pkcs7_padding(text)
         local text_length = string.len(text)
         local amount_to_pad = 32 - (text_length % 32)
     
         if amount_to_pad == 0 then
             amount_to_pad = 32
         end
         local pad = string.char(amount_to_pad) return text .. string.rep(pad,amount_to_pad)
     end
     
     local function encrypt (text)
         text = pkcs7_padding(text)
         text = aes_256_cbc_with_iv:encrypt(text)
         return base64_encode(text)
     end
     
     print(decrypt(encrypt('linbc')))

    接着是python版本的

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import base64
    
    from Crypto.Cipher import AES
    
    
    import binascii
    import StringIO
    
    class PKCS7Encoder(object):
        '''
        RFC 2315: PKCS#7 page 21
        Some content-encryption algorithms assume the
        input length is a multiple of k octets, where k > 1, and
        let the application define a method for handling inputs
        whose lengths are not a multiple of k octets. For such
        algorithms, the method shall be to pad the input at the
        trailing end with k - (l mod k) octets all having value k -
        (l mod k), where l is the length of the input. In other
        words, the input is padded at the trailing end with one of
        the following strings:
    
                 01 -- if l mod k = k-1
                02 02 -- if l mod k = k-2
                            .
                            .
                            .
              k k ... k k -- if l mod k = 0
    
        The padding can be removed unambiguously since all input is
        padded and no padding string is a suffix of another. This
        padding method is well-defined if and only if k < 256;
        methods for larger k are an open issue for further study.
        '''
        def __init__(self, k=16):
            self.k = k
    
        ## @param text The padded text for which the padding is to be removed.
        # @exception ValueError Raised when the input padding is missing or corrupt.
        def decode(self, text):
            '''
            Remove the PKCS#7 padding from a text string
            '''
            nl = len(text)
            val = int(binascii.hexlify(text[-1]), 16)
    
            if val > self.k:
                raise ValueError('Input is not padded or padding is corrupt')
    
            l = nl - val
    
            return text[:l]
    
        ## @param text The text to encode.
        def encode(self, text):
            '''
            Pad an input string according to PKCS#7
            '''
            l = len(text)
            output = StringIO.StringIO()
            val = self.k - (l % self.k)
    
            for _ in xrange(val):
                output.write('%02x' % val)
    
            return text + binascii.unhexlify(output.getvalue())
    
    
    
    # 使用256位的AES,Python会根据传入的Key长度自动选择,长度为16时使用128位的AES
    key = 'a12e93c9edadeaa47eb1aeabe27dabef'
    mode = AES.MODE_CBC
    #iv = '1234567812345678'  # AES的CBC模式使用IV
    iv = 'a12e93c9edadeaa4'  # AES的CBC模式使用IV
    
    encoder = PKCS7Encoder()
    text = "This is for test."
    
    def encrypt(data):
        encryptor = AES.new(key, AES.MODE_CBC, iv)
        padded_text = encoder.encode(data)
        encrypted_data = encryptor.encrypt(padded_text)
    
        return base64.b64encode(encrypted_data)
    
    def decrypt(data):
        cipher = base64.b64decode(data)
        decryptor = AES.new(key, AES.MODE_CBC, iv)
        plain = decryptor.decrypt(cipher)
    
        return encoder.decode(plain)
    
    #encrypted_text = encrypt(text)
    encrypted_text = 'MD1ZOvuyvut4VEed4rf+8YKaOHyECJK/RWLcfVsJwjAEZp8Hhi1zi7oH3PLSygjFCAxCRJqMBzm/qhreznkg34Vgbho+zwprTgl4M0c0lRkvLzWzXmSYG8pcqth1qnbNSwQeS3MPuofgVXR0SGMTIzicCXDlmwQV9uvIJekgES2LMse4pVndcrftI9f6UbIiT085DhAaiV9yGsV3r4FES+LnwP9ZNi58TButNC9owyKh9RuRn7z04LfNy++7iLjzk/HurOkBkJewHSchLER+pK94qhg6Lj8mW7dl+y5j3wbXY9SodNK+S8LDRYCa1JyZ/w8rffUK8YCY+jCT3ZmV8G5vdUENTqsrB4jX87C+XQCY9WEG+VQ5MK5XlhhvMPZyn2NLZUi6gW1HjqE6i/uefzq/LFl47cL2Hmr/cLbfI5rF+d1hMAIZGNnRxjYkVVvipEwRSlkD47ZVFLiWRKPusB7Lke3mnGJ1O+5eQnREL7Q/xpRT+3JuCcOqZIZJFFrJXMj9CXsJGMXxFkfnKT3UAhOi/lRA65Vwt1BEswHuZzLLHquyEYQMc3cOW1vy1Fv4zpYkjHYmxB1g50gwVryrEW2kY58sDdxwDYua3jLwERk='
    
    clean_text = decrypt(encrypted_text)
    
    print "encrypted_text:", encrypted_text
    print "clean_text: ", clean_text

    再来个php版本的

    <?php
    
    //function aes256EcbPkcs7PaddingEncrypt($key, $data) {
    //    $padding = 16 - (strlen($data) % 16);
    //    $data .= str_repeat(chr($padding), $padding);
    //    return mcrypt_encrypt(MCRYPT_RIJNDAEL_256, hash('SHA256', $key, true), $data, MCRYPT_MODE_ECB);
    //}
    //
    //function aes256EcbPkcs7PaddingDecrypt($key, $data) {
    //    $data = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, hash('SHA256', $key, true), $data, MCRYPT_MODE_ECB);
    //    $padding = ord($data[strlen($data) - 1]); 
    //    return substr($data, 0, -$padding); 
    //}
    
    $txt="MD1ZOvuyvut4VEed4rf+8YKaOHyECJK/RWLcfVsJwjAEZp8Hhi1zi7oH3PLSygjFCAxCRJqMBzm/qhreznkg34Vgbho+zwprTgl4M0c0lRkvLzWzXmSYG8pcqth1qnbNSwQeS3MPuofgVXR0SGMTIzicCXDlmwQV9uvIJekgES2LMse4pVndcrftI9f6UbIiT085DhAaiV9yGsV3r4FES+LnwP9ZNi58TButNC9owyKh9RuRn7z04LfNy++7iLjzk/HurOkBkJewHSchLER+pK94qhg6Lj8mW7dl+y5j3wbXY9SodNK+S8LDRYCa1JyZ/w8rffUK8YCY+jCT3ZmV8G5vdUENTqsrB4jX87C+XQCY9WEG+VQ5MK5XlhhvMPZyn2NLZUi6gW1HjqE6i/uefzq/LFl47cL2Hmr/cLbfI5rF+d1hMAIZGNnRxjYkVVvipEwRSlkD47ZVFLiWRKPusB7Lke3mnGJ1O+5eQnREL7Q/xpRT+3JuCcOqZIZJFFrJXMj9CXsJGMXxFkfnKT3UAhOi/lRA65Vwt1BEswHuZzLLHquyEYQMc3cOW1vy1Fv4zpYkjHYmxB1g50gwVryrEW2kY58sDdxwDYua3jLwERk=";
    $txt=base64_decode($txt);
    $key="a12e93c9edadeaa47eb1aeabe27dabef";
    $iv ='a12e93c9edadeaa4';
    
    $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');
    mcrypt_generic_init($module, $key, $iv);
    $data = mdecrypt_generic($module, $txt);
    mcrypt_generic_deinit($module);
    mcrypt_module_close($module);
    
    $padding = ord($data[strlen($data) - 1]); 
    $result = substr($data, 0, -$padding); 
    echo $result;
    
    exit();
    
    ?>

    php果然是...很省事的语言..看他多简短啊.

  • 相关阅读:
    线程基础1
    组合数学的卡特兰数 TOJ 3551: Game of Connections
    2017ACM/ICPC广西邀请赛-重现赛(感谢广西大学)
    Codeforces Round #430 (Div. 2)
    线代之高斯消元
    牛客网Wannafly模拟赛
    TOJ3039: 材质贴图
    AtCoder Grand Contest 019
    TOJ 3974: Region n条直线m个圆最多将圆分为几个区域
    AIM Tech Round 4 (Div. 2)
  • 原文地址:https://www.cnblogs.com/linbc/p/9710487.html
Copyright © 2011-2022 走看看