ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Python과 Java에서 사용가능한 AES 암/복호화 모듈
    Python 2018. 1. 24. 14:14

    엔진단은 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 

Designed by Tistory.