728x90
아래 함수는 Javascript 에서 암호화된 문자열을 PHP 언어에서 복호화 성공한 암호화 KEY 문자열과 복호화 KEY 문자열을 가지고 테스트 진행했다. 함수가 제대로 동작되는 걸 확인했다.
Android Java 코드로 RSA 암호화/복호화 함수 구현 것을 chatGPT에게 변환 요청한 것은 성공되지 못하고 실패했다.
chatGPT가 이기종 언어에서 구현한 코드를 변환 요청하면 대부분 실패하는 거 같다.
Front-End 언어에서 암호화하고 Spring Boot 에서 복호화가 정상적으로 되어야 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
package com.example.springjwt.util;
import org.springframework.stereotype.Component;
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
@Component
public class RSAUtil {
/**
* 2048비트 RSA 키 쌍 생성
*/
public KeyPair generateRSAKeyPair() {
try {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(2048);
return keyPairGenerator.generateKeyPair();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("Failed to generate RSA key pair", e);
}
}
/**
* Base64 인코딩된 공개키 문자열을 PublicKey 객체로 변환 (X.509)
*/
public PublicKey getPublicKeyFromBase64(String base64PublicKey) {
try {
byte[] decodedKey = Base64.getDecoder().decode(base64PublicKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(new X509EncodedKeySpec(decodedKey));
} catch (Exception e) {
throw new RuntimeException("Failed to retrieve public key from Base64", e);
}
}
/**
* Base64 인코딩된 개인키 문자열을 PrivateKey 객체로 변환 (PKCS8)
*/
public PrivateKey getPrivateKeyFromBase64(String base64PrivateKey) {
try {
byte[] decodedKey = Base64.getDecoder().decode(base64PrivateKey);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(decodedKey));
} catch (Exception e) {
throw new RuntimeException("Failed to retrieve private key from Base64", e);
}
}
/**
* Base64 인코딩된 공개키 문자열을 받아 RSA 암호화 수행 (RSA/ECB/PKCS1Padding 사용)
*/
public String encryptRSA(String plainText, String base64PublicKey) {
try {
PublicKey publicKey = getPublicKeyFromBase64(base64PublicKey);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encryptedBytes);
} catch (Exception e) {
throw new RuntimeException("RSA encryption failed", e);
}
}
/**
* Base64 인코딩된 개인키 문자열을 받아 RSA 복호화 수행 (RSA/ECB/PKCS1Padding 사용)
*/
public String decryptRSA(String encryptedText, String base64PrivateKey) {
try {
PrivateKey privateKey = getPrivateKeyFromBase64(base64PrivateKey);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));
return new String(decryptedBytes, StandardCharsets.UTF_8);
} catch (Exception e) {
throw new RuntimeException("RSA decryption failed", e);
}
}
}
|
테스트 하는 방법은 아래와 같이 파일을 추가해서 하면 된다.
RSA Key 쌍을 생성하지 않아도 된다. RSA Key 쌍을 Linux 시스템에서 파일로 생성한 것으로 테스트를 진행했고 잘 동작되는 걸 확인했다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
package com.example.springjwt.util;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
@Component
public class RSAUtilRunner implements CommandLineRunner {
private final RSAUtil rsaUtil;
public RSAUtilRunner(RSAUtil rsaUtil) {
this.rsaUtil = rsaUtil;
}
@Override
public void run(String... args) throws Exception {
// 1. RSA 키 쌍 생성
KeyPair keyPair = rsaUtil.generateRSAKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
// 2. Base64로 인코딩하여 키 출력
String base64PublicKey = java.util.Base64.getEncoder().encodeToString(publicKey.getEncoded());
String base64PrivateKey = java.util.Base64.getEncoder().encodeToString(privateKey.getEncoded());
System.out.println("----- RSA 키 쌍 생성 완료 -----");
System.out.println("공개키 (Base64): " + base64PublicKey);
System.out.println("개인키 (Base64): " + base64PrivateKey);
// 3. 암호화 테스트
String originalText = "Hello, Spring Boot with RSA!";
System.out.println("\n원본 텍스트: " + originalText);
String encryptedText = rsaUtil.encryptRSA(originalText, base64PublicKey);
System.out.println("암호화된 텍스트: " + encryptedText);
// 4. 복호화 테스트
String decryptedText = rsaUtil.decryptRSA(encryptedText, base64PrivateKey);
System.out.println("복호화된 텍스트: " + decryptedText);
}
}
|
다음에는 실제 React 에서 비밀번호를 암호화해서 전송하고, Spring Boot 에서 복호화 성공 여부를 확인하려고 한다.
728x90