2017-10-18 11 views
0

키 쌍을 생성하는 코드를 작성했지만 저장하고 다시 사용할 수있는 방법이 있는지 궁금합니다. 여기 자바 비대칭 암호화에서 키 쌍을 저장하고 다시 사용하는 방법은 무엇입니까?

는 쌍 generaes 코드이다

공공 정적 무효 메인 (문자열 []를 인수) {예외

String plainText = "Hello world"; 

    Map<String, Object> keys = getRSAKeys(); 

    PrivateKey privateKey = (PrivateKey) keys.get("private"); 
    PublicKey publicKey = (PublicKey) keys.get("public"); 

    System.out.println(privateKey.getEncoded()); 

    System.out.println(publicKey.getEncoded()); 



    String encrypted = encryptMessage(plainText, privateKey); 


    System.out.println(encrypted); 

    String decrypted = decryptMessage(plainText, publicKey, encrypted); 

    System.out.println(decrypted); 

} 

private static Map<String, Object> getRSAKeys() throws Exception { 

    KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); 
    keyPairGenerator.initialize(2048); 
    KeyPair keyPair = keyPairGenerator.generateKeyPair(); 
    PrivateKey privateKey = keyPair.getPrivate(); 
    PublicKey publicKey = keyPair.getPublic(); 
    Map<String, Object> keys = new HashMap<String, Object>(); 
    keys.put("private", privateKey); 
    keys.put("public", publicKey); 

    return keys; 

} 
+0

물론 :

또한 여기 당신이 원하는 것을 정확히 할 몇 가지 예제 코드입니다. 어떻게 든 데이터를 유지하십시오. 프로그램의 수명 내에서 참조를 유지하십시오. 프로그램의 수명 외에도 - 직렬화가 가능하므로 직렬화 할 수 있습니다. (물론 직렬화 된 키를 안전하게 유지하는 것에 대해 걱정해야합니다 ...) –

+0

다음과 같이 왜 'KeyPair'객체를 반환 할 수 있는지 Map에 넣어야합니까? –

+0

감사합니다. Andy, 어떻게 그렇게 할 것입니까? – TheRealJoeWilson

답변

-1

https://docs.oracle.com/javase/tutorial/security/apisign/step2.html 슬로우 - 좋은 엔트리 포인트.

package mx.playground.security; 

import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.nio.file.Files; 
import java.security.KeyFactory; 
import java.security.PrivateKey; 
import java.security.PublicKey; 
import java.security.spec.PKCS8EncodedKeySpec; 
import java.security.spec.X509EncodedKeySpec; 
import java.util.Base64; 

import javax.crypto.Cipher; 

public class AppForStackOverflow { 

    public static final int KEY_SIZE = 2048; 

    public static final String PUBLIC_KEY_X509 = "C:\\workspace\\rsa-pair\\public-key"; 
    public static final String PUBLIC_KEY_PKCS1 = "C:\\workspace\\rsa-pair\\public-key-pkcs1"; 
    public static final String PUBLIC_KEY_PEM = "C:\\workspace\\rsa-pair\\public-key-pem"; 

    public static final String PRIVATE_KEY_PKCS8 = "C:\\workspace\\rsa-pair\\private-key"; 
    public static final String PRIVATE_KEY_PKCS1 = "C:\\workspace\\rsa-pair\\private-key-pkcs1"; 
    public static final String PRIVATE_KEY_PEM = "C:\\workspace\\rsa-pair\\private-key-pem"; 

    public static final String SIGNATURE_PATH = "C:\\workspace\\rsa-pair\\signature"; 

    public static final String PRIVATE_KEY_PATH = PRIVATE_KEY_PKCS8; 
    public static final String PUBLIC_KEY_PATH = PUBLIC_KEY_X509; 

    public static void main(String[] args) { 
     generateRsaKeysPair(); 
     encryptDecryptTest(); 

     // symmetric encryption example, use it to store your Private Key in safe manner 
     String message = "test message"; 
     String rightPass = "ABCDEF"; // for AES password should be at least 16 chars 
     String wrongPass = "zzz"; 

     byte[] encryptedMessage = symmetricEncrypt(message.getBytes(), rightPass); 
     System.out.print(new String(encryptedMessage)); 

     byte[] decryptedMessage = symmetricDecrypt(encryptedMessage, rightPass); 
     System.out.println(new String(decryptedMessage)); 

    }  

    public static void generateRsaKeysPair() { 
     try { 
      KeyPairGeneratorJdk kpg = new KeyPairGeneratorJdk(KEY_SIZE, "RSA"); 

      PublicKey publicKey = kpg.getPublicKey(); 
      PrivateKey privateKey = kpg.getPrivateKey(); 

      save(PUBLIC_KEY_PATH, publicKey.getEncoded()); 
      save(PRIVATE_KEY_PATH, privateKey.getEncoded()); 
     } catch (Exception e) { 
      throw new RuntimeException("Failed to execute generateRsaKeysPair()", e);   
     } 
    } 

    public static void encryptDecryptTest() { 
     try { 
      byte[] privateKeyBytes = read(PRIVATE_KEY_PATH); 
      byte[] publicKeyBytes = read(PUBLIC_KEY_PATH); 

      KeyFactory kf = KeyFactory.getInstance("RSA"); 
      PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(privateKeyBytes); 
      PrivateKey privateKey = kf.generatePrivate(privateKeySpec); 

      X509EncodedKeySpec spec = new X509EncodedKeySpec(publicKeyBytes); 
      PublicKey publicKey = kf.generatePublic(spec); 

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

      // doing encryption 
      String message = "test message"; 
      cipher.init(Cipher.ENCRYPT_MODE, publicKey); 
      byte[] encodedMessage = cipher.doFinal(message.getBytes("UTF-8")); 
      System.out.println("ENCRYPTED: " + new String(encodedMessage)); 

      // doing decryption 
      cipher.init(Cipher.DECRYPT_MODE, privateKey); 
      byte[] decodedMessage = cipher.doFinal(encodedMessage); 
      System.out.println("DECRYPTED: " + new String(decodedMessage)); 
     } catch (Exception e) { 
      throw new RuntimeException("Failed to execute encryptDecryptTest()", e); 
     } 
    } 

    private static void save(String path, byte[] data) { 
     try { 
      File file = new File(path); 
      file.getParentFile().mkdirs(); 

      try (FileOutputStream fos = new FileOutputStream(file)){ 
       fos.write(Base64.getEncoder().encode(data)); 
       fos.flush(); 
      }; 
     } catch (IOException e) { 
      throw new RuntimeException("Failed to save data to file: " + path, e); 
     } 
    } 

    private static byte[] read(String path) { 
     try { 
      return Base64.getDecoder().decode(Files.readAllBytes(new File(path).toPath())); 
     } catch (IOException e) { 
      throw new RuntimeException("Failed to read data from file: " + path, e); 
     } 
    } 

    /* 
    * Use this to encrypt your private key before saving it to disk 
    */ 
    public static byte[] symmetricEncrypt(byte[] data, String password) { 
     try { 
      SecretKeySpec secretKey = new SecretKeySpec(password.getBytes(), "AES"); 
      Cipher cipher = Cipher.getInstance("AES"); 
      cipher.init(Cipher.ENCRYPT_MODE, secretKey); 
      byte[] result = cipher.doFinal(data); 
      return result; 
     } catch (Exception e) { 
      throw new RuntimeException("Failed to execute symmetricEncrypt()", e); 
     } 
    } 

    public static byte[] symmetricDecrypt(byte[] data, String password) { 
     try { 
      SecretKeySpec secretKey = new SecretKeySpec(password.getBytes(), "AES"); 
      Cipher cipher = Cipher.getInstance("AES"); 
      cipher.init(Cipher.DECRYPT_MODE, secretKey); 
      byte[] result = cipher.doFinal(data); 
      return result; 
     } catch (Exception e) { 
      throw new RuntimeException("Failed to execute symmetricEncrypt()", e); 
     } 
    } 

} 
+0

안전하지 않습니다. 용납 될 수없는. – EJP

+0

재미있게하기 위해 비공개 키에 대한 패스와 함께 대칭 암호화를 수행하는 코드를 추가하여 안전성이 낮고 수용 할 수 있도록했습니다. –