결제 관련 API 연동(VAN, PG, 간편결제 등) 할 경우 RSA암복호화 과정을 거치게되는데
이 부분에 대한 샘플 코드를 작성해 보았다.
Apache Commons Codec 다운로드
commons.apache.org/proper/commons-codec/
Codec – Home
Apache Commons Codec Apache Commons Codec (TM) software provides implementations of common encoders and decoders such as Base64, Hex, Phonetic and URLs. Impetus Codec was formed as an attempt to focus development effort on one definitive implementation of
commons.apache.org
프로젝트 라이브러리에 추가.

PublicKey와 PrivateKey 파일을 생성
package com.ubpay.keypair;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
//
// RSA Key 파일 생성
//
// Created by netcanis on 2019/04/29.
// Copyright © 2019 netcanis. All rights reserved.
//
// Download Apache Commons Codec
// https://commons.apache.org/proper/commons-codec/download_codec.cgi
public class GenKeys
{
private KeyPairGenerator keyGen;
private KeyPair pair;
private PrivateKey privateKey;
private PublicKey publicKey;
// RSA 초기화 및 키 생성
public GenKeys(int keysize) throws NoSuchAlgorithmException, NoSuchProviderException {
this.keyGen = KeyPairGenerator.getInstance("RSA");
this.keyGen.initialize(keysize);
this.pair = this.keyGen.generateKeyPair();
this.publicKey = pair.getPublic();
this.privateKey = pair.getPrivate();
}
public PublicKey getPublicKey() {
return this.publicKey;
}
public PrivateKey getPrivateKey() {
return this.privateKey;
}
public void writeToFile(String path, byte[] key) throws IOException {
File f = new File(path);
f.getParentFile().mkdirs();
FileOutputStream fos = new FileOutputStream(f);
fos.write(key);
fos.flush();
fos.close();
}
public static void main(String[] args) {
GenKeys genKeys;
try {
// 1024bit key pair 생성
genKeys = new GenKeys(1024);
System.out.println(genKeys.publicKey);
System.out.println(genKeys.privateKey);
// 바이너리 파일로 저장
genKeys.writeToFile("KeyPair/public.key", genKeys.getPublicKey().getEncoded());
genKeys.writeToFile("KeyPair/private.key", genKeys.getPrivateKey().getEncoded());
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
System.err.println(e.getMessage());
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
}
생성 결과

생성된 키를 이용하여 암복호화 테스트
package com.ubpay.rsaTest;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.DSAPrivateKeySpec;
import java.security.spec.DSAPublicKeySpec;
import java.security.spec.EncodedKeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.apache.commons.codec.binary.Base64;
//
// RSA 암복호화 및 테스트
//
// Created by netcanis on 2019/04/29.
// Copyright © 2019 netcanis. All rights reserved.
//
public class RSAEncryption
{
private Cipher cipher;
public RSAEncryption() throws NoSuchAlgorithmException, NoSuchPaddingException{
this.cipher = Cipher.getInstance("RSA");
}
// 주어진 파일을 byte array로 읽기
public byte[] getFileInBytes(File f) throws IOException{
FileInputStream fis = new FileInputStream(f);
byte[] fbytes = new byte[(int) f.length()];
fis.read(fbytes);
fis.close();
return fbytes;
}
// X509EncodedKey
public PublicKey getPublic(String filename) throws Exception {
byte[] keyBytes = Files.readAllBytes(new File(filename).toPath());
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
// PKCS8EncodedKeySpec
public PrivateKey getPrivate(String filename) throws Exception {
byte[] keyBytes = Files.readAllBytes(new File(filename).toPath());
//byte[] decoded = Base64.getDecoder().decode(keyBytes);
//println(new String(decoded)); // Outputs "Hello"
//Base64 codec = new Base64();
//byte[] decoded = codec.decode(keyBytes);
//System.out.println( new String(decoded) ); // Outputs "Hello"
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(spec);
}
// public key로 암호화
public String encrypt(String str, PublicKey key) throws NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException{
this.cipher.init(Cipher.ENCRYPT_MODE, key);
return Base64.encodeBase64String(cipher.doFinal(str.getBytes("UTF-8")));
}
// private key로 복호화
public String decrypt(String str, PrivateKey key) throws InvalidKeyException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException{
this.cipher.init(Cipher.DECRYPT_MODE, key);
return new String(cipher.doFinal(Base64.decodeBase64(str)), "UTF-8");
}
// hex to byte[]
public byte[] hexStringToByteArray(String s) {
int len = s.length();
byte[] data = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return data;
}
// byte[] to hex
public String byteArrayToHexString(byte[] bytes){
StringBuilder sb = new StringBuilder();
for(byte b : bytes){
sb.append(String.format("%02X", b&0xff));
}
return sb.toString();
}
public static void main(String[] args) throws Exception {
RSAEncryption ac = new RSAEncryption();
// 공개키
PublicKey publicKey = ac.getPublic("KeyPair/public.key");
// 개인키
PrivateKey privateKey = ac.getPrivate("KeyPair/private.key");
// 원문
String msg = "test message";
System.out.println("----------------------------------------------------");
System.out.println(":::: TEST 암호화 및 복호화 ::::");
// 암호화 원문 BASE64
String encryptedString = ac.encrypt(msg, publicKey);
// 복호화
String decryptedString = ac.decrypt(encryptedString, privateKey);
System.out.println("----------------------------------------------------");
System.out.println(
"원문 = " + msg + "\n" +
"공개키 암호화 = " + encryptedString + "\n" +
"개인키 복호화 = " + decryptedString
);
System.out.println("----------------------------------------------------");
}
}
결과 :
--------------------------------------------------------------------------
:::: TEST 암호화 및 복호화 ::::
--------------------------------------------------------------------------
원문 = test message
공개키 암호화 = gz2WQHCyHxsPV5IB0xehk8RSbGrhGR86nQRGj09CphxiIAjRsCony8myWfRGJgDVyK6ixuK13gtL/20j4K5c1GcCKxPT9xqYaa6tBxTakho9klHNAO6KhQJK0nGeIQRDpZ1qecB6pPMsRqVVO5rb81NFqbjLKMoqi2tO1f55/iM=
개인키 복호화 = test message
--------------------------------------------------------------------------
2020/12/17 - [OS/Mac OS X] - OpenSSL을 이용한 Key 정보 Text 변환
2020/12/17 - [iOS/Tips] - URL query 파싱 및 json string 변환
2020/12/16 - [개발노트] - Code 128 Barcode의 Check Digit 계산방법
2020/12/15 - [iOS/Tips] - 디버깅 차단 처리 (Anti Debug)
2020/12/14 - [iOS/Tips] - bundle id 알아내기
2020/12/12 - [AI/Algorithm] - 2D 충돌처리
2020/12/11 - [iOS/Swift] - UIViewController 스위칭
2020/12/11 - [개발노트] - PlantUML 설치 (Mac OS X)
2020/12/10 - [iOS/Objective-C] - 웹뷰에서 javascript 함수 동기식 호출
2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (2/2)
2020/12/10 - [iOS/Tips] - Fat Static Library 빌드 (1/2)
2020/12/10 - [iOS/Tips] - Custom UserAgent 설정
2020/12/10 - [iOS/Tips] - CocoaPods 설치 및 제거
2020/12/10 - [iOS/Tips] - Clang diagnostic 경고 무시하기
2020/12/10 - [개발노트] - Bluetooth UUID
'개발 > Note' 카테고리의 다른 글
Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended (0) | 2020.12.17 |
---|---|
OpenSSL을 이용한 Key 정보 Text 변환 (0) | 2020.12.17 |
Code 128 Barcode의 Check Digit 계산방법 (0) | 2020.12.16 |
PlantUML 설치 (Mac OS X) (0) | 2020.12.11 |
특수문자 발음 (0) | 2020.12.11 |