본문 바로가기

dev/java(egov)

java rsa 암호화, 복호화

반응형
rsa 암호화, 복호화

RSA 알고리즘은 다음과 같은 다양한 상황에서 사용될 수 있습니다:

  1. 안전한 데이터 전송: 데이터를 안전하게 전송해야 하는 경우에 RSA를 사용할 수 있습니다. 예를 들어, 클라이언트와 서버 간의 통신에서 데이터의 기밀성을 보장하고자 할 때 사용됩니다. HTTPS 프로토콜에서 SSL/TLS 세션을 설정할 때 RSA가 사용됩니다.
  2. 전자 서명: 데이터의 인증과 무결성 검증을 위해 사용됩니다. 데이터의 송신자가 데이터를 서명하여 자신의 신원을 입증하고, 데이터가 변경되지 않았음을 수신자가 검증할 수 있습니다.
  3. 키 교환: Diffie-Hellman 키 교환과 같은 프로토콜과 함께 사용하여 안전한 방식으로 키를 교환할 수 있습니다. 이는 대칭 암호화 키를 안전하게 교환하는 데 사용됩니다.
  4. 디지털 인증서: RSA는 디지털 인증서에서 주로 사용됩니다. 웹 사이트, 애플리케이션 등의 신원을 확인하고 안전한 연결을 보장하기 위해 사용됩니다.
  5. 보안 토큰: RSA는 보안 토큰(예: 스마트 카드)에서 개인키를 보호하고 사용자 인증을 위한 도구로 사용됩니다.
  6. 보안 프로토콜: RSA는 다양한 보안 프로토콜에서 암호화와 인증 기능을 제공하는 데 사용됩니다. 예를 들어, SSH, IPsec 등에서 사용될 수 있습니다.
  7. 전자상거래: 전자상거래 플랫폼에서는 사용자의 개인정보와 금융 데이터를 안전하게 보호하기 위해 RSA가 사용될 수 있습니다.

RSA는 공개키 암호화의 가장 대표적인 기술로서, 데이터의 기밀성, 인증, 무결성 보장 등 다양한 정보 보안 요구 사항을 해결하는 데 중요한 역할을 합니다. 그러나 RSA의 성능 문제나 키 관리의 어려움 등을 고려하여 특정 상황에서는 다른 암호화 기술을 고려할 필요가 있습니다.

 
 
rsa 암복호화 java 소스
package hoho.util;

import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

/**
 * RSA 암호화 및 복호화 유틸리티 클래스입니다.
 */
public class RsaUtil {

    private static final String INSTANCE_TYPE = "RSA";

    /**
     * 2048비트 RSA 키 페어를 생성합니다.
     * @return 생성된 RSA 키 페어
     * @throws NoSuchAlgorithmException 암호화 알고리즘이 지원되지 않는 경우
     */
    public static KeyPair generateKeypair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(INSTANCE_TYPE);
        keyPairGen.initialize(2048, new SecureRandom());
        return keyPairGen.genKeyPair();
    }

    /**
     * 주어진 평문을 RSA 공개키를 사용하여 암호화합니다.
     * @param plainText 암호화할 평문
     * @param publicKey RSA 공개키
     * @return Base64로 인코딩된 암호화된 문자열
     * @throws NoSuchAlgorithmException 암호화 알고리즘이 지원되지 않는 경우
     * @throws InvalidKeySpecException 잘못된 키 사양이 제공된 경우
     * @throws NoSuchPaddingException 패딩 알고리즘이 지원되지 않는 경우
     * @throws InvalidKeyException 잘못된 키가 제공된 경우
     * @throws IllegalBlockSizeException 잘못된 블록 크기가 제공된 경우
     * @throws BadPaddingException 잘못된 패딩이 제공된 경우
     */
    public static String rsaEncode(String plainText, String publicKey)
            throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        Cipher cipher = Cipher.getInstance(INSTANCE_TYPE);
        cipher.init(Cipher.ENCRYPT_MODE, convertPublicKey(publicKey));
        byte[] plainTextByte = cipher.doFinal(plainText.getBytes());
        return base64EncodeToString(plainTextByte);
    }

    /**
     * 주어진 암호화된 문자열을 RSA 개인키를 사용하여 복호화합니다.
     * @param encryptedPlainText 암호화된 문자열
     * @param privateKey RSA 개인키
     * @return 복호화된 평문
     * @throws NoSuchAlgorithmException 암호화 알고리즘이 지원되지 않는 경우
     * @throws InvalidKeySpecException 잘못된 키 사양이 제공된 경우
     * @throws NoSuchPaddingException 패딩 알고리즘이 지원되지 않는 경우
     * @throws InvalidKeyException 잘못된 키가 제공된 경우
     * @throws IllegalBlockSizeException 잘못된 블록 크기가 제공된 경우
     * @throws BadPaddingException 잘못된 패딩이 제공된 경우
     */
    public static String rsaDecode(String encryptedPlainText, String privateKey)
            throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException,
            InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
        byte[] encryptedPlainTextByte = Base64.getDecoder().decode(encryptedPlainText);
        Cipher cipher = Cipher.getInstance(INSTANCE_TYPE);
        cipher.init(Cipher.DECRYPT_MODE, convertPrivateKey(privateKey));
        return new String(cipher.doFinal(encryptedPlainTextByte));
    }

    /**
     * Base64로 인코딩된 공개키 문자열을 RSA PublicKey 객체로 변환합니다.
     * @param publicKey Base64로 인코딩된 공개키 문자열
     * @return RSA 공개키 객체
     * @throws NoSuchAlgorithmException 암호화 알고리즘이 지원되지 않는 경우
     * @throws InvalidKeySpecException 잘못된 키 사양이 제공된 경우
     */
    public static PublicKey convertPublicKey(String publicKey)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] publicKeyByte = Base64.getDecoder().decode(publicKey);
        KeyFactory keyFactory = KeyFactory.getInstance(INSTANCE_TYPE);
        return keyFactory.generatePublic(new X509EncodedKeySpec(publicKeyByte));
    }

    /**
     * Base64로 인코딩된 개인키 문자열을 RSA PrivateKey 객체로 변환합니다.
     * @param privateKey Base64로 인코딩된 개인키 문자열
     * @return RSA 개인키 객체
     * @throws NoSuchAlgorithmException 암호화 알고리즘이 지원되지 않는 경우
     * @throws InvalidKeySpecException 잘못된 키 사양이 제공된 경우
     */
    public static PrivateKey convertPrivateKey(String privateKey)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        byte[] privateKeyByte = Base64.getDecoder().decode(privateKey);
        KeyFactory keyFactory = KeyFactory.getInstance(INSTANCE_TYPE);
        return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(privateKeyByte));
    }

    /**
     * 바이트 배열을 Base64로 인코딩한 문자열로 변환합니다.
     * @param byteData 바이트 배열
     * @return Base64로 인코딩된 문자열
     */
    public static String base64EncodeToString(byte[] byteData) {
        return Base64.getEncoder().encodeToString(byteData);
    }
}

 

 

 

rsa 예제

test 코드에 작성하여 테스트 코드를 작성했습니다.

package hoho_test;

import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import hoho.util.RsaUtil;

class RSA {

	private static final Logger _log = LoggerFactory.getLogger(RSA.class);
	
	private static String publicKey;
	private static String privateKey;
		
	@Test
	void test() throws NoSuchAlgorithmException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
		rsakey();
		ras2048();
	}

	public void rsakey() throws NoSuchAlgorithmException {

	    KeyPair keyPair = RsaUtil.generateKeypair();
	    	
	    publicKey = RsaUtil.base64EncodeToString(keyPair.getPublic().getEncoded());
	    privateKey = RsaUtil.base64EncodeToString(keyPair.getPrivate().getEncoded());
	}

	public void ras2048() throws InvalidKeyException, InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
		
		_log.info("publicKey 값 : " + publicKey);
		_log.info("privateKey 값 : " + privateKey);
				
		String str = "rsa 잘 되는가?";
		
		String str_encrypt = RsaUtil.rsaEncode(str, publicKey);
		
		_log.info("rsa 암호화 : " + str_encrypt);
		
		String str_decrypt = RsaUtil.rsaDecode(str_encrypt, privateKey);
		_log.info("rsa 복호화 : " + str_decrypt);
	}

}

 

 

rsa 예제 test 결과

 

 

java rsa 코드, 예제, 결과 영상 등입니다.

반응형