• Home
  • About
    • lahuman photo

      lahuman

      열심히 사는 아저씨

    • Learn More
    • Facebook
    • LinkedIn
    • Github
  • Posts
    • All Posts
    • All Tags
  • Projects

AES Encryption/Decryption 테스트

24 Jan 2018

Reading time ~2 minutes

Python과 Java에서 사용가능한 AES 암/복호화 모듈 개발

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

Python 소스

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 소스

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 = "12345678901234567890123456789012";
        String iv = "1234567890123456";

        String beforeCipher = "abcd";
        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)));
        plaintextLength += fillChar; //pad 
        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



AESJAVAPython Share Tweet +1