개발

RSA - javax.crypto.IllegalBlockSizeException: Data must not be longer than 245 bytes 오류

개미v 2021. 2. 2. 12:48

오류 내용

RSA 2048 크기의 Key로 큰 사이즈의 데이터를 암호화를 할 경우 발생

Exception in thread "main" javax.crypto.IllegalBlockSizeException: Data must not be longer than 245 bytes
	at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:346)
	at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:391)
	at javax.crypto.Cipher.doFinal(Cipher.java:2168)
	at RSA.encrypt(RSA.java:58)
	at Main.main(Main.java:18)

 

오류 원인

RSA 알고리즘에서 2048 크기의 Key로는 256바이트 이하만 암호화 가능

 

해결 방법

아래 링크에 해결방법 나와 있음

https://stackoverflow.com/questions/10007147/getting-a-illegalblocksizeexception-data-must-not-be-longer-than-256-bytes-when

 

getting a IllegalBlockSizeException: Data must not be longer than 256 bytes when using rsa

I am using rsa key to encrypt a long string which I will send to my server(will encrypt it with server's public key and my private key) But it throws an exception like javax.crypto.

stackoverflow.com

 

해결 예시

평문을 AES로 암호화 하고, AES KEY값을 RSA로 암호화 하고 상대에게 암호문(AES암호화) + AES_KEY(RSA암호화)를 전달하는 형태로 구현

	// 평문
	String originData = "Lorem stra, ................... per inceptos himenaeos.";
	byte[] plainText = originData.getBytes();

	System.out.println("원본 : " + originData);
		
	///////////// 암호화 과정 ///////////// 		
	// AES로 평문 암호화
	Key aeskey = AES.generateKey();
	String dataAesBase64 = AES.encrypt(plainText, aeskey);

	// RSA 개인키로 AES_KEY 암호화
	String AesKeyRsaBase64 = RSA.encrypt(aeskey.getEncoded(), Cert.PRIVATE_KEY);

	// 상대에게 DATA(AES암호화) + AES_KEY(RSA암호화) 형태로 전달
	Map<String, Object> map = new HashMap<String, Object>();
	map.put("ENC_DATA", dataAesBase64);
	map.put("ENC_AES_KEY", AesKeyRsaBase64);
	String encTotalData = map.toString();
		
	System.out.println("암호문 : " + encTotalData);
	///////////// 암호화 과정 끝 ///////////// 
		
		
	///////////// 복호화 과정 /////////////
	// RSA 공개키로 AES_KEY 복호화
	String aesKeyRsaBase64 = (String) map.get("ENC_AES_KEY");
	String aesKeyBase64 = RSA.decrypt(aesKeyRsaBase64, Cert.PUBLIC_KEY);
	
	// AES로 DATA 복호화
	byte[] aesKeyByte = Base64.getDecoder().decode(aesKeyBase64);
	SecretKey aesKey = new SecretKeySpec(aesKeyByte, 0, aesKeyByte.length, "AES");
	String dataBase64 = AES.decrypt((String) map.get("ENC_DATA"), aesKey);
	String resultData = new String(Base64.getDecoder().decode(dataBase64));
		
	System.out.println("복호화 : " + resultData);
	///////////// 복호화 과정 끝 /////////////