我编写了生成密钥对的代码,但想知道是否有任何方法可以保存和重用它们?
以下是产生该对的代码:
public static void main(String [] args)抛出异常{
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 :(得分:-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 = "0123456789ABCDEF"; // 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);
}
}
}