Edw*_*ard 6 java encryption rsa bouncycastle public-key-encryption
我有一个包含公共RSA密钥的文件(生成时ssh-keygen).我想读取文件并生成一个PublicKey对象.
在此之前我转换了文件,因为阅读原始文件似乎是不可能的:
# http://unix.stackexchange.com/questions/220354/how-to-convert-public-key-from-pem-to-der-format/220356#220356
ssh-keygen -f ~/.ssh/id_rsa.pub -e -m PEM > ~/.ssh/id_rsa.pub.pem
openssl rsa -RSAPublicKey_in -in ~/.ssh/id_rsa.pub.pem -inform PEM -outform DER -out ~/.ssh/id_rsa.pub.der -RSAPublicKey_out
Run Code Online (Sandbox Code Playgroud)
从Java - 使用现有公钥文件加密字符串我定义了函数readFileBytes:
public static byte[] readFileBytes(String filename) throws IOException {
Path path = Paths.get(System.getProperty("user.home") + filename);
return Files.readAllBytes(path);
}
Run Code Online (Sandbox Code Playgroud)
现在我想读取文件并生成PublicKey对象,但我找不到办法做到这一点; java.security.spec.RSAPublicKeySpec不提供适合的构造函数并java.security.spec.X509EncodedKeySpec抛出错误java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: algid parse error, not a sequence:
//RSAPublicKeySpec publicSpec = new RSAPublicKeySpec(readFileBytes("/.ssh/id_rsa.pub.der"));
// No fitting construktor
X509EncodedKeySpec publicSpec = new X509EncodedKeySpec(readFileBytes("/.ssh/id_rsa.pub.der"));
// Gives: "algid parse error, not a sequence"
Run Code Online (Sandbox Code Playgroud)
我有一个项目,其中(RSA)加密是必要的,这就是我重建publicKey给定publicKey的byte数组,只是从文件中读取.
public PublicKey reconstruct_public_key(String algorithm, byte[] pub_key) {
PublicKey public_key = null;
try {
KeyFactory kf = KeyFactory.getInstance(algorithm);
EncodedKeySpec pub_key_spec = new X509EncodedKeySpec(pub_key);
public_key = kf.generatePublic(pub_key_spec);
} catch(NoSuchAlgorithmException e) {
System.out.println("Could not reconstruct the public key, the given algorithm oculd not be found.");
} catch(InvalidKeySpecException e) {
System.out.println("Could not reconstruct the public key");
}
return public_key;
}
Run Code Online (Sandbox Code Playgroud)
然后你可以调用类似于这个调用的过程, reconstruct_public_key("RSA", readFileBytes("path/to/your/publicKey/file"));
编辑:我自己尝试(将公钥写入文件,读取该文件并重建密钥).这有效:
public static void main(String args[]) {
String path = "./pub_key_test.txt";
// Generate a keypair to write to file
KeyPair kp = generate_key();
PublicKey pub_key = kp.getPublic();
File file = new File(path);
try {
// Write to file
file.createNewFile();
FileOutputStream out = new FileOutputStream(path);
out.write(pub_key.getEncoded()); // Write public key to the file
out.close();
// Read from file
FileInputStream in = new FileInputStream(path);
byte[] pub_key_arr = new byte[in.available()];
in.read(pub_key_arr, 0, in.available());
in.close();
// Reconstruct public key
PublicKey reconstructed_pub_key = reconstruct_public_key("RSA", pub_key_arr);
} catch(IOException e) {
System.out.println("Could not open the file : " + e.getStackTrace());
}
}
Run Code Online (Sandbox Code Playgroud)
这是generate_key程序:
public KeyPair generate_key() {
while(true) { // Else the compiler will complain that this procedure does not always return a "KeyPair"
try {
final KeyPairGenerator key_generator = KeyPairGenerator.getInstance("RSA");
key_generator.initialize(2048); // Keys of 2048 bits (minimum key length for RSA keys) are safe enough (according to the slides 128bit keys > 16 years to brute force it)
final KeyPair keys = key_generator.generateKeyPair();
return keys;
} catch(NoSuchAlgorithmException e) {
System.out.println("The given encryption algorithm (RSA) does not exist. -- generate_key() - Cryptography.");
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果你测试这个,你会看到publicKey成功重建.
编辑:我尝试使用该ssh-keygen工具自己做.这就是我做的:
.PEM格式).DER格式化,因此Java可以使用它.这就是我进行转换的方式,与您的转换有点不同:
openssl rsa -in private_key_file.pem -pubout -outform DER -out java_readable_file.der
Run Code Online (Sandbox Code Playgroud)
我在这里做了文件读取,这与你的差别不大.我测试了这个并且Java成功地重建了公钥.