背景:

   因项目需要,需要将一个python2编写的aes加密方式改为java实现。

1.源python2实现

from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
import hashlib
import urllib

class aesCrypt():
    def __init__(self, undealKey):
        key = turnMd5(undealKey)
        print undealKey
        dealKey = dealKeyAndIV(key.lower())

        self.key = dealKey
        # self.iv = iv
        self.mode = AES.MODE_ECB
        self.BS = AES.block_size
        # 补位
        self.pad = lambda s: s + (self.BS - len(s) % self.BS) * chr(self.BS - len(s) % self.BS)
        self.unpad = lambda s: s[0:-ord(s[-1])]

    def encrypt(self, text):
        text = self.pad(text)
        cryptor = AES.new(self.key, self.mode)
        # 目前AES-128 足够目前使用
        ciphertext = cryptor.encrypt(text)
        # 把加密后的字符串转化为16进制字符串
        return b2a_hex(ciphertext)

    # 解密后,去掉补足的空格用strip() 去掉
    def decrypt(self, text):
        cryptor = AES.new(self.key, self.mode)
        plain_text = cryptor.decrypt(a2b_hex(text))
        return self.unpad(plain_text.rstrip('\0'))



def turnHex(character):
<略>

def debugPrint(str):
    print str

def dealKeyAndIV(undealKey):

<略>
def turnMd5(str): <略>

2.经历

  1. 我只有python3的环境,因使用到

Crypto

这个package的很难安装上去,经过多种尝试,使用pycryptodome替代,故需要修改部分代码

  2. 改成python3的文件

from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex
import hashlib
import urllib

class aesCrypt():
    def __init__(self, undealKey):
        key = turnMd5(undealKey)
        print(undealKey)
        dealKey = dealKeyAndIV(key.lower())

        self.key = dealKey
        # self.iv = iv
        self.mode = AES.MODE_ECB
        self.BS = AES.block_size
        # 补位
        self.pad = lambda s: s + (self.BS - len(s) % self.BS) * chr(self.BS - len(s) % self.BS)
        self.unpad = lambda s: s[0:-ord(s[-1])]

    def encrypt(self, text):
        text = self.pad(text)
        #finalkey=bytes([239,159,125,206,247,119,225,116,254,91,100,130,255,144,207,70])
        cryptor = AES.new(bytes(self.key), self.mode)
        # 目前AES-128 足够目前使用
        #ss=bytes([67, 122, 99, 115, 81, 111, 68, 112, 67, 47, 67, 75, 48, 108, 98, 90, 99, 68, 47, 115, 88, 87, 52, 65, 43, 105, 119, 83, 72, 122, 88, 109, 55, 110, 98, 54, 102, 85, 89, 84, 56, 89, 117, 120, 102, 79, 110, 78, 70, 69, 120, 104, 97, 48, 68, 115, 83, 112, 89, 85, 84, 57, 49, 98, 113, 66, 120, 77, 107, 108, 52, 74, 105, 99, 72, 56, 49, 112, 105, 71, 106, 116, 103, 77, 87, 69, 71, 57, 43, 52, 69, 120, 54, 86, 82, 56, 56, 51, 102, 88, 74, 52, 112, 86, 117, 110, 120, 68, 117, 68, 100, 56, 53, 100, 109, 109, 88, 82, 106, 110, 48, 118, 107, 99, 115, 105, 89, 102, 97, 51, 110, 122, 72, 85, 122, 54, 67, 107, 55, 74, 85, 109, 115, 49, 73, 79, 99, 78, 76, 86, 66, 53, 87, 110, 53, 110, 106, 68, 76, 83, 65, 70, 114, 84, 106, 71, 68, 87, 110, 73, 69, 61, 4, 4, 4, 4])
        #ss=text.encode()
        #print(a2b_hex(ss))
        #print(a2b_hex(ss))
        ciphertext = cryptor.encrypt(text.encode("utf-8"))
        # 把加密后的字符串转化为16进制字符串
        return b2a_hex(ciphertext)

    # 解密后,去掉补足的空格用strip() 去掉
    def decrypt(self, text):
        cryptor = AES.new(self.key, self.mode)
        plain_text = cryptor.decrypt(a2b_hex(text))
        return self.unpad(plain_text.rstrip('\0'))



def turnHex(character):
    value = ord(character)
    # print value
    temp = value - 48
    if value - 48 > 9:
        if (value - 97 <= 5) & (value - 97 >= 0):
            temp = value - 87
    return tempdef dealKeyAndIV(undealKey):
    flag = 0
    result=[]
    # debugPrint 'len=',len(undealKey)/2
    while flag < len(undealKey)/2:
        characterH = undealKey[flag*2]
        # debugPrint characterH
        highBit = turnHex(characterH) * 16
        # debugPrint highBit
        characterL = undealKey[flag*2+1]
        # debugPrint characterL
        lowBit = turnHex(characterL)
        # debugPrint lowBit
        ascValue = highBit+lowBit
        # debugPrint ascValue
        result.append(ascValue)
        # debugPrint result
        flag += 1
        # print '-------'
    return resultdef turnMd5(str):
    m2 = hashlib.md5()
    data = str.encode(encoding="utf-8")
    m2.update(data)
    return m2.hexdigest()

改写java程序

   private static byte[] pading(String str){
        byte[] strBs=str.getBytes();
        int n=strBs.length/16;
        byte[] pading=new byte[16*(n+1)];
        System.arraycopy(strBs, 0, pading, 0, strBs.length);
        //不足16位的进行补足
        int len=16 - str.length()%16;
        for(int i=strBs.length;i<pading.length;i++){
            pading[i]=(byte)len;
        }
        return pading;
    }
    
    public static String bytesToHexString(byte[] src){  
        StringBuilder stringBuilder = new StringBuilder("");  
        if (src == null || src.length <= 0) {  
            return null;  
        }  
        for (int i = 0; i < src.length; i++) {  
            int v = src[i] & 0xFF;  
            String hv = Integer.toHexString(v);  
            if (hv.length() < 2) {  
                stringBuilder.append(0);  
            }  
            stringBuilder.append(hv);  
        }  
        return stringBuilder.toString();  
    }
    
    public static String MD5Encode(String source, String encoding, boolean uppercase) {
        String result = null;
        try {
            result = source;
            // 获得MD5摘要对象
            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
            // 使用指定的字节数组更新摘要信息
            messageDigest.update(result.getBytes(encoding));
            // messageDigest.digest()获得16位长度
            result = bytesToHexString(messageDigest.digest());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return uppercase ? result.toUpperCase() : result;
    }
    
    public static Integer turnHex(char c){
        int ret=0;
        switch(c){
        case '0':return 0;
            case '1':return 1;
           case '2':return 2;
           case '3':return 3;
           case '4':return 4;
           case '5':return 5;
            case '6':return 6;
            case '7':return 7;
           case '8':return 8;
           case '9':return 9;
           case 'a':return 10;
           case 'b':return 11;
           case 'c':return 12;
           case 'd':return 13;
           case 'e':return 14;
           case 'f':return 15;
        }
        return ret;
    }
    
    private static byte[] dealKeyAndIV(String str){
        byte[] keys=new byte[16];
        int flag = 0;
        while(flag < str.length()/2){
            char characterH =str.charAt(flag*2);
            int highBit = turnHex(characterH) * 16;
            char characterL = str.charAt(flag*2+1);
            int lowBit = turnHex(characterL);
            int ascValue = highBit+lowBit;
            keys[flag]=(byte) ascValue;
            //System.out.println(ascValue);
            flag += 1;
        }        
        return keys;
    }


    public static String encrypt() throws Exception {
        try {
            String data = "CzcsQoDpC/CK0lbZcD/sXW4A+iwSHzXm7nb6fUYT8YuxfOnNFExha0DsSpYUT91bqBxMkl4JicH81piGjtgMWEG9+4Ex6VR883fXJ4pVunxDuDd85dmmXRjn0vkcsiYfa3nzHUz6Ck7JUms1IOcNLVB5Wn5njDLSAFrTjGDWnIE=";
            String key = "IMgzwYRjA3sZgiXl";
            String md5key=MD5Encode(key,"utf-8",false); //'ef9f7dcef777e174fe5b6482ff90cf46'
            
            //String finalKey = dealKeyAndIV(md5key);
            //System.out.println(finalKey.length());
            //System.out.println("c3afc29f7dc38ec3b777c3a174c3be5b64c282c3bfc290c38f46".length());
            //String ss=bytesToHexString(finalKey.getBytes());//b'c3afc29f7dc38ec3b777c3a174c3be5b64c282c3bfc290c38f46'
            
            Cipher cipher = Cipher.getInstance("AES/ECB/NoPadding");
            int blockSize = cipher.getBlockSize();
            byte[] plaintext=pading(data);
/*            byte[] dataBytes = data.getBytes();
            int plaintextLength = dataBytes.length;
            if (plaintextLength % blockSize != 0) {
                plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
            }

            byte[] plaintext = new byte[plaintextLength];
            System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);*/
            byte[] keys=dealKeyAndIV(md5key);
           // byte[] keys=new byte[]{(byte)239,(byte)159,125,(byte)206,(byte)247,119,(byte)225,116,(byte)254,91,100,(byte)130,(byte)255,(byte)144,(byte)207,70};
            SecretKeySpec keyspec = new SecretKeySpec(keys, "AES");
            cipher.init(Cipher.ENCRYPT_MODE, keyspec);
            //byte[] bb=new byte[]{67, 122, 99, 115, 81, 111, 68, 112, 67, 47, 67, 75, 48, 108, 98, 90, 99, 68, 47, 115, 88, 87, 52, 65, 43, 105, 119, 83, 72, 122, 88, 109, 55, 110, 98, 54, 102, 85, 89, 84, 56, 89, 117, 120, 102, 79, 110, 78, 70, 69, 120, 104, 97, 48, 68, 115, 83, 112, 89, 85, 84, 57, 49, 98, 113, 66, 120, 77, 107, 108, 52, 74, 105, 99, 72, 56, 49, 112, 105, 71, 106, 116, 103, 77, 87, 69, 71, 57, 43, 52, 69, 120, 54, 86, 82, 56, 56, 51, 102, 88, 74, 52, 112, 86, 117, 110, 120, 68, 117, 68, 100, 56, 53, 100, 109, 109, 88, 82, 106, 110, 48, 118, 107, 99, 115, 105, 89, 102, 97, 51, 110, 122, 72, 85, 122, 54, 67, 107, 55, 74, 85, 109, 115, 49, 73, 79, 99, 78, 76, 86, 66, 53, 87, 110, 53, 110, 106, 68, 76, 83, 65, 70, 114, 84, 106, 71, 68, 87, 110, 73, 69, 61, 4, 4, 4, 4};
            byte[] encrypted = cipher.doFinal(plaintext);
            return bytesToHexString(encrypted);
            //return new sun.misc.BASE64Encoder().encode(encrypted);

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
   

注意点

1. 是模式ECB,BCB等

2.填充方式

   自定义填充

 

posted on 2017-09-21 17:43  一天不进步,就是退步  阅读(1712)  评论(0编辑  收藏  举报