-
Python과 Java에서 사용가능한 AES 암/복호화 모듈Python 2018. 1. 24. 14:14728x90
엔진단은 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 처리를 한다.
참고 자료
728x90'Python' 카테고리의 다른 글
Python3.7 설치와 몇가지 새로운 사실 & pip install 시 SSL 오류 처리 (0) 2018.10.05 Python]paramiko 모듈에서 su 명령어로 계정 전환 (0) 2018.05.18 Python에서 class 선언시 object를 꼭 상속 받자 (0) 2018.04.17 파이썬을 이용한 압축 해제와 동시에 파일 이름 변경 (0) 2018.04.17 Python에서 virualenv 과 virtualenvwrapper 설치하기 (0) 2017.12.21