알쓸전컴(알아두면 쓸모있는 전자 컴퓨터)

jsencrypt(RSA) <-> JAVA RSA 사용법 본문

Web

jsencrypt(RSA) <-> JAVA RSA 사용법

백곳 2018. 12. 29. 17:56

jsencrypt(RSA) <-> JAVA RSA 사용법


웹에서 javascirpt 와 java 간의 서로 사용 방법으로 해도 될것 같습니다.


일단 RSA에서 Private Key(암호와 하는 키)는 몇가지 형식이 있습니다.


일단 대표적인 2가지를 알아 보겠습니다.


아래 키를 보시면 -----BEGIN RSA PRIVATE KEY-----  이라고 표시 되서 키가 나오는것은 PKCS#1


-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQCkd5GnJ/ktL+GCzH6JUwO963DCGC8Nhdg5vBkzF4OPTvn0d4/M
1PfXbrofaiz6CpvGJxav4IRfRdSKpCQ5lHozxBwMrLX7umeDO7sgd3aJEbcSqN9J
tp2iMMJlyFGamA2/IFAeb51iP8v7iWnzhldDKEZMWPiTV61C2rKwDW7ybQIDAQAB
AoGBAItZY+elTtKihwg0C+J+m+UG33sU0ok6poIEhbVsbuO1nsMrqoN6zqOSBdEo
PQN+iY3TAL30FTREDlmJycefrglhjaF7b8JkaeilaZHQv4UUHVPEt7/8IElPwSCq
dT6M6XdWbI7thHFgsXOTivuvHHO2VTr0zMSz7C/O2s669yoBAkEA3f1rcwDl7x2A
oiWFqEXPkC/BKHrXdWnn3eUmAgDdk69elw+Y/tE960TQiHpM5vDpE64job9xIesD
QgBpCqzcvQJBAL2qEVe5TLq++jsU7QvRlA2+dTsl6L1Yu4pl0oNF4+r+Wlcl3hiY
qMmnMvJ8I5tqeDzBPW8oDNoaKJrS0ZZ7P3ECQEcNBYcZkn6mArXjLJRfQ7/yiPBb
4PpDm2L6JOAfRswuJShUZbOpZRgYPmZwPozsLq2N3vm2PI+OmMxXNUelbEECQGtE
KQTNFtkzM4CAqEQb5rkTM2gdW5DjA0YVqkZ2G54G9n79Oqv8gtFxj33WuainQZNS
0vTv2LztOHO/sauCzvECQQCDIiki4VrCbdhJU3Uie0dkQ84Ys+uADCaCUDB/+x1l
XTxf3Qj14gLqnl/srXvBMxZOlyPti5bPtviX54VPtyQf
-----END RSA PRIVATE KEY----


-----BEGIN PRIVATE KEY-----  이라고 표시 되서 키가 나오는것은 PKCS#8


-----BEGIN PRIVATE KEY-----
MIICXQIBAAKBgQCkd5GnJ/ktL+GCzH6JUwO963DCGC8Nhdg5vBkzF4OPTvn0d4/M
1PfXbrofaiz6CpvGJxav4IRfRdSKpCQ5lHozxBwMrLX7umeDO7sgd3aJEbcSqN9J
tp2iMMJlyFGamA2/IFAeb51iP8v7iWnzhldDKEZMWPiTV61C2rKwDW7ybQIDAQAB
AoGBAItZY+elTtKihwg0C+J+m+UG33sU0ok6poIEhbVsbuO1nsMrqoN6zqOSBdEo
PQN+iY3TAL30FTREDlmJycefrglhjaF7b8JkaeilaZHQv4UUHVPEt7/8IElPwSCq
dT6M6XdWbI7thHFgsXOTivuvHHO2VTr0zMSz7C/O2s669yoBAkEA3f1rcwDl7x2A
oiWFqEXPkC/BKHrXdWnn3eUmAgDdk69elw+Y/tE960TQiHpM5vDpE64job9xIesD
QgBpCqzcvQJBAL2qEVe5TLq++jsU7QvRlA2+dTsl6L1Yu4pl0oNF4+r+Wlcl3hiY
qMmnMvJ8I5tqeDzBPW8oDNoaKJrS0ZZ7P3ECQEcNBYcZkn6mArXjLJRfQ7/yiPBb
4PpDm2L6JOAfRswuJShUZbOpZRgYPmZwPozsLq2N3vm2PI+OmMxXNUelbEECQGtE
KQTNFtkzM4CAqEQb5rkTM2gdW5DjA0YVqkZ2G54G9n79Oqv8gtFxj33WuainQZNS
0vTv2LztOHO/sauCzvECQQCDIiki4VrCbdhJU3Uie0dkQ84Ys+uADCaCUDB/+x1l
XTxf3Qj14gLqnl/srXvBMxZOlyPti5bPtviX54VPtyQf
-----END PRIVATE KEY----


여기에서 보통 JAVA 에서 지원 되는 라이브러리는 PKCS#8이 대부분이고 예제 대부분이 또한 PKCS#8 입니다.


하지만 jsencrypt 만들어 주는 키는  

 

PKCS#1 입니다.


java 에서 난감하게 됩니다 .


그래서 PKCS#1을 java 에서 읽을수 있는 방법을 기록 합니다.


여기서에 추가 적으로 필요한 라이브러리는


MAVEN 에 해당 라이브러리 추가 필요 합니다.


  <dependencies>
      <dependency>
          <groupId>com.sun.jini</groupId>
          <artifactId>sun-util</artifactId>
          <version>2.1</version>
      </dependency>
  </dependencies>



package apitest.com;

import java.io.IOException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
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.RSAPrivateCrtKeySpec;
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;

import sun.security.util.DerInputStream;
import sun.security.util.DerValue;

public class MainA {

    public static void main(String[] args) throws IOException, GeneralSecurityException {
        // TODO Auto-generated method stub
String sPublicKey2 = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCMZXFISQhUtIXT8dQGC6KX/fnV" +
      "/bxCLYPJXAc/1xlgLyurlqusivW6AzYlQYsmAX7v50JyvYxeOxdDKkcz+tU8BhLY" +
      "beZSJZ9tkrtYsem+knegRKujKbKWTm3GIPPK1hiifhc9fC+lGKv2199VHBjcFtZc" +
      "hmq14ef17FFJqDVEyQIDAQAB";
         String sPrivateKey2 = "MIICXQIBAAKBgQCMZXFISQhUtIXT8dQGC6KX/fnV/bxCLYPJXAc/1xlgLyurlqus" +
               "ivW6AzYlQYsmAX7v50JyvYxeOxdDKkcz+tU8BhLYbeZSJZ9tkrtYsem+knegRKuj" +
               "KbKWTm3GIPPK1hiifhc9fC+lGKv2199VHBjcFtZchmq14ef17FFJqDVEyQIDAQAB" +
               "AoGAZwbmS7J0b5yN/Mug2NLe/YS+Oz/ZUAMQi8qB82JI1+GlvWRzFMpgqqFCsbJY" +
               "h4pfeXOOup7IjDn2xy4WVFnE8gbwBlYZI5mFaX8sFawO+liieKPZJV9z/6GTOmQo" +
               "M01z3KMP6XbGPWgix6o7L8ivs8H4gDzq15D5lf5RiLxGcjUCQQD7TdGn1yrPrmTW" +
               "uu8wwRBHcpI+He2Ry1NjYmPLZj20hDfBhbgLoj7PNM7x3bfn1ULg5H2UFnygMvq4" +
               "qMIGeoDLAkEAjwUQ9hYV+Uy1AsSf8pbJDHF7tcXFLQ1qlmoeOrt/RZmJhn0sgndD" +
               "9k7o2OQj86aRKKLJIXFPtyiY8HlC1+gCOwJBAIh0rv0WJtbyeSroAm1UyAQjwCke" +
               "kxtxbmwuxsVxVNwqVyQr+c3HYZedsyk+HVgzQsdfCplYxH8wb1fJuuFNr5UCQHsi" +
               "iITnZQncIih8850gd36wIivRV78/Qtq4CMjWb3CUDZTuJqk5WBkzvUQnwFBhw66x" +
               "4OtbLJ/sYyj/ri5HwcsCQQCaZiuXi6M3cZPtWDNuRch6q6sQDqDME8K0O8A7/Uto" +
               "fUiF3Y57fqft3UZUROyjwmJmTdzx3ecdthaVYszU6iU2";
     byte[] bPublicKey2 = Base64.getDecoder().decode(sPublicKey2.getBytes());
     PublicKey publicKey2 = null;
    
     byte[] bPrivateKey2 = Base64.getDecoder().decode(sPrivateKey2.getBytes());
     PrivateKey privateKey2 = null;
    
     try {
     KeyFactory keyFactory2 = KeyFactory.getInstance("RSA");
    
     X509EncodedKeySpec publicKeySpec
     = new X509EncodedKeySpec(bPublicKey2);
     publicKey2 = keyFactory2.generatePublic(publicKeySpec);
    
         DerInputStream derReader = new DerInputStream(Base64.getDecoder().decode(sPrivateKey2));
         DerValue[] seq = derReader.getSequence(0);
         // skip version seq[0];
         BigInteger modulus = seq[1].getBigInteger();
         BigInteger publicExp = seq[2].getBigInteger();
         BigInteger privateExp = seq[3].getBigInteger();
         BigInteger prime1 = seq[4].getBigInteger();
         BigInteger prime2 = seq[5].getBigInteger();
         BigInteger exp1 = seq[6].getBigInteger();
         BigInteger exp2 = seq[7].getBigInteger();
         BigInteger crtCoef = seq[8].getBigInteger();
        
         RSAPrivateCrtKeySpec keySpec =
         new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp, prime1, prime2, exp1, exp2, crtCoef);
         KeyFactory keyFactory = KeyFactory.getInstance("RSA");
         privateKey2 = keyFactory.generatePrivate(keySpec);
    
    
     } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
     e.printStackTrace();
     }

     String sPlain1 = "Welcome to RSA";
     String sPlain2 = null;

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

     // 공개키 이용 암호화
     cipher.init(Cipher.ENCRYPT_MODE, publicKey2);
     byte[] bCipher1 = cipher.doFinal(sPlain1.getBytes());
     String sCipherBase64 = Base64.getEncoder().encodeToString(bCipher1);
     System.out.println(sCipherBase64);
     // 개인키 이용 복호화
     byte[] bCipher2 = Base64.getDecoder().decode(sCipherBase64.getBytes());
     cipher.init(Cipher.DECRYPT_MODE, privateKey2);
     byte[] bPlain2 = cipher.doFinal(bCipher2);
     sPlain2 = new String(bPlain2);
     } catch (NoSuchAlgorithmException e) {
     e.printStackTrace();
     } catch (NoSuchPaddingException e) {
     e.printStackTrace();
     } catch (InvalidKeyException e) {
     e.printStackTrace();
     } catch (IllegalBlockSizeException e) {
     e.printStackTrace();
     } catch (BadPaddingException e) {
     e.printStackTrace();
     }
     System.out.println("sPlain1 : " + sPlain1); // 평문(원본)
     System.out.println("sPlain2 : " + sPlain2); // 평문(암호화후 복호화된 평문)

    }

}



아래 부분이 핵심이라고 볼수 있습니다.


         DerInputStream derReader = new DerInputStream(Base64.getDecoder().decode(sPrivateKey2));
         DerValue[] seq = derReader.getSequence(0);
         // skip version seq[0];
         BigInteger modulus = seq[1].getBigInteger();
         BigInteger publicExp = seq[2].getBigInteger();
         BigInteger privateExp = seq[3].getBigInteger();
         BigInteger prime1 = seq[4].getBigInteger();
         BigInteger prime2 = seq[5].getBigInteger();
         BigInteger exp1 = seq[6].getBigInteger();
         BigInteger exp2 = seq[7].getBigInteger();
         BigInteger crtCoef = seq[8].getBigInteger();
        
         RSAPrivateCrtKeySpec keySpec =
         new RSAPrivateCrtKeySpec(modulus, publicExp, privateExp, prime1, prime2, exp1, exp2, crtCoef);
         KeyFactory keyFactory = KeyFactory.getInstance("RSA");
         privateKey2 = keyFactory.generatePrivate(keySpec);


추후 jsencrypt  라이브러리와 와  사용할때 잘 호환 되게 사용 가능 할것 습니다.



Comments