개발

Java RSA crypto

빠빠담 2020. 12. 26. 18:42
반응형

1. 쉘에서 키를 생성하여 자바에서 사용

키 생성은 아래에서 확인하자

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;

public interface KeyReader {

    PrivateKey getPrivateKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException;

    PublicKey getPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException;

}
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

public class RsaKeyReader implements KeyReader {

    private final String PRIVATE_KEY_PATH = "/path/rsa-key/private_key.der";
    private final String PUBLIC_KEY_PATH = "/path/rsa-key/public_key.der";

    @Override
    public PrivateKey getPrivateKey() throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {

        byte[] keyBytes = Files.readAllBytes(Paths.get(PRIVATE_KEY_PATH));

        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");

        return kf.generatePrivate(spec);

    }

    @Override
    public PublicKey getPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException, IOException {

        byte[] keyBytes = Files.readAllBytes(Paths.get(PUBLIC_KEY_PATH));

        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");

        return kf.generatePublic(spec);

    }

}

2. 키를 자바에서 생성하여 사용

public class GenRsaKey implements KeyReader{

    private KeyPair keyPair;

    public GenRsaKey() throws NoSuchAlgorithmException {
        keyPair = genKeyPair();
    }

    @Override
    public PrivateKey getPrivateKey(){
        return keyPair.getPrivate();
    }

    @Override
    public PublicKey getPublicKey(){
        return keyPair.getPublic();
    }


    private KeyPair genKeyPair() throws NoSuchAlgorithmException {

        SecureRandom secureRandom = new SecureRandom();

        KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");

        gen.initialize(1024, secureRandom);


        KeyPair keyPair = gen.genKeyPair();

        return keyPair;

    }
}

3. RSA를 이용하여 암복호화

import org.apache.tomcat.util.codec.binary.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;

public class RsaCrypto {

    /**
     * Public Key로 RSA 암호화를 수행합니다.
     * @param plainText 암호화할 평문입니다.
     * @param publicKey 공개키 입니다.
     * @return
     */

    public static String encryptRSA(String plainText, PublicKey publicKey)
            throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {

        Cipher cipher = Cipher.getInstance("RSA");

        cipher.init(Cipher.ENCRYPT_MODE, publicKey);

        byte[] bytePlain = cipher.doFinal(plainText.getBytes());

        return Base64.encodeBase64String(bytePlain);

    }

    /**
     * Private Key로 RAS 복호화를 수행합니다.
     * @param encrypted 암호화된 이진데이터를 base64 인코딩한 문자열 입니다.
     * @param privateKey 복호화를 위한 개인키 입니다.
     * @return
     * @throws Exception
     */

    public static String decryptRSA(String encrypted, PrivateKey privateKey)
            throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {

        Cipher cipher = Cipher.getInstance("RSA");

        byte[] byteEncrypted = Base64.decodeBase64(encrypted.getBytes());

        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        byte[] bytePlain = cipher.doFinal(byteEncrypted);

        String decrypted = new String(bytePlain, "utf-8");

        return decrypted;

    }

}

쉘에서 키를 생성

https://stackoverflow.com/questions/11410770/load-rsa-public-key-from-file

Generate a 2048-bit RSA private key

$ openssl genrsa -out private\_key.pem 2048

Convert private Key to PKCS#8 format (so Java can read it)

$ openssl pkcs8 -topk8 -inform PEM -outform DER -in private\_key.pem -out private\_key.der -nocrypt

Output public key portion in DER format (so Java can read it)

$ openssl rsa -in private_key.pem -pubout -outform DER -out public_key.der

Private key

import java.io.*;
import java.nio.*;
import java.security.*;
import java.security.spec.*;

public class PrivateKeyReader {

  public static PrivateKey get(String filename)
  throws Exception {

    byte[] keyBytes = Files.readAllBytes(Paths.get(filename));

    PKCS8EncodedKeySpec spec =
      new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    return kf.generatePrivate(spec);
  }
}

Public key

import java.io.*;
import java.nio.*;
import java.security.*;
import java.security.spec.*;

public class PublicKeyReader {

  public static PublicKey get(String filename)
    throws Exception {

    byte[] keyBytes = Files.readAllBytes(Paths.get(filename));

    X509EncodedKeySpec spec =
      new X509EncodedKeySpec(keyBytes);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    return kf.generatePublic(spec);
  }
}
반응형

'개발' 카테고리의 다른 글

Java - GC  (0) 2021.02.16
FFMPEG - to mp4  (0) 2021.01.17
ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION  (0) 2020.12.24
Sap - Jco 를 통한 function 호출  (0) 2020.12.09
Redmine 운영 3 - agile  (0) 2020.12.07