엔진단은 Python으로 되어 있고, WEB은 JAVA로 되어 있는 프로젝트에서 AES 256기반의 암/복호화 처리를 한다.


단순하게 KEY와 SALT만 마춰주면 된다.

Python Source

from Crypto.Cipher import AES

import base64

import hashlib


BS = AES.block_size

pad = lambda s: s + (BS - len(s) % BS) * chr(BS - len(s) % BS)

unpad = lambda s : s[0:-ord(s[-1])]


if __name__ == '__main__':

    key = "12345678901234567890123456789012"; # 32bit

    iv = '1234567890123456' # 16bit

    

    beforeCipher = 'abcd'

    print 'Input string: ' + beforeCipher


    cipher = AES.new(key, AES.MODE_CBC, IV=iv)

    beforeCipher = pad(beforeCipher)

    afterCipher = base64.b64encode(cipher.encrypt(beforeCipher))

    print 'Cipher string: ' + afterCipher


    cipher = AES.new(key, AES.MODE_CBC, IV=iv)

    deciphed = cipher.decrypt(base64.b64decode(afterCipher))

    deciphed = unpad(deciphed)

    print 'Deciphed string: [' + deciphed +']'

결과

Input string: abcd

Cipher string: nf2mDLb4L36PWlXz3mNPTw==

Deciphed string: [abcd]


JAVA Source

package lahuman;


import org.junit.Assert;


import javax.crypto.*;

import javax.crypto.spec.IvParameterSpec;

import javax.crypto.spec.SecretKeySpec;

import java.io.UnsupportedEncodingException;

import java.security.InvalidAlgorithmParameterException;

import java.security.InvalidKeyException;

import java.security.MessageDigest;

import java.security.NoSuchAlgorithmException;

import java.security.spec.AlgorithmParameterSpec;

import java.util.Arrays;

import java.util.Base64;


import static org.hamcrest.Matchers.is;



public class Test {


    @org.junit.Test

    public void test() throws UnsupportedEncodingException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {

        String key = "1234567901234567980123456789012";

        String iv = "1234567890123456";


         String beforeCipher = "123456789012345";

        System.out.println("Input string: " + beforeCipher);


        SecretKey keyspec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");

        AlgorithmParameterSpec ivspec = new IvParameterSpec(iv.getBytes("UTF-8"));


        //Encription

        Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");

        cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);

        int blockSize = cipher.getBlockSize();

        byte[] dataBytes = beforeCipher.getBytes("UTF-8");


        //find fillChar & pad

        int plaintextLength = dataBytes.length;

        int fillChar = ((blockSize - (plaintextLength % blockSize)));

        if (plaintextLength % blockSize != 0) {

            plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));

        }

        byte[] plaintext = new byte[plaintextLength];

        Arrays.fill(plaintext, (byte) fillChar);

        System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);


        byte[] cipherBytes = cipher.doFinal(plaintext);

        String afterCiphered = new String(Base64.getEncoder().encodeToString(cipherBytes));

        System.out.println("Cipher string: " + afterCiphered);


        //Decription

        cipher = Cipher.getInstance("AES/CBC/NoPadding");

        cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);

        byte[] base64decoded = Base64.getDecoder().decode(afterCiphered.getBytes("UTF-8"));

        byte[] aesdecode = cipher.doFinal(base64decoded);

        

        // unpad

        byte[] origin = new byte[aesdecode.length - (aesdecode[aesdecode.length - 1])];

        System.arraycopy(aesdecode, 0, origin, 0, origin.length);


        String originStr =  new String(origin, "UTF-8");

        System.out.println("Decipher string: [" + originStr + "]");

    }

}

결과

Input string: abcd

Cipher string: nf2mDLb4L36PWlXz3mNPTw==

Decipher string: [abcd]


Java에서 Python의 pad, unpad와 똑같이 동작 하기 위하여 Encryption시 fillChar을 찾고 pad처리를 하고, Decryption시 unpad 처리를 한다.


참고 자료

Python Java AES 

Posted by lahuman