[英]How to generate PublicKey object from a file in Java
我有一個包含公共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
從Java - 使用現有公鑰文件加密String我定義了函數readFileBytes
:
public static byte[] readFileBytes(String filename) throws IOException {
Path path = Paths.get(System.getProperty("user.home") + filename);
return Files.readAllBytes(path);
}
現在我想讀取文件並生成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"
我有一個項目,其中(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;
}
然后你可以調用類似於這個調用的過程, 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());
}
}
這是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.");
}
}
}
如果您對此進行測試,您將看到publicKey
已成功重建。
編輯:我嘗試使用ssh-keygen
工具自己做。 這就是我做的:
.PEM
格式) .DER
格式,因此Java可以使用它。 這就是我進行轉換的方式,與您的轉換有點不同:
openssl rsa -in private_key_file.pem -pubout -outform DER -out java_readable_file.der
我在這里做了文件讀取,這與你的差別不大。 我測試了這個並且Java成功地重建了公鑰。
創建RSA私鑰
openssl genrsa -out rsaprivkey.pem 1024
生成DER格式的公鑰。
openssl rsa -in rsaprivkey.pem -pubout -outform DER -out rsapubkey.der
我們使用此代碼從X.509證書中提取公鑰RSA或DSA。
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
/**
* This class is capable of extracting a public key from a X.509 certficate
* and returning the PublicKey representation from a referenced byte array.
*
*/
public class ExtractPublicKey {
// Certificate Filename (Including Path Info)
private static final String certFilename = "cacert.pem";
// Public Key Filename (Including Path Info)
private static final String pubKeyFilename = "rsapublic.key";
public static PublicKey generatePublicKey(byte[] encodedKey)
throws NoSuchAlgorithmException, InvalidKeySpecException {
X509EncodedKeySpec pubSpec = new X509EncodedKeySpec(encodedKey);
boolean isSupportedKey = false;
KeyFactory factory;
PublicKey retKey = null;
//first try the DSA alg
try {
factory = KeyFactory.getInstance("DSA");
retKey = factory.generatePublic(pubSpec);
isSupportedKey = true;
} catch (InvalidKeySpecException e) {
System.out.println("Could not create DSA Public Key: " + e.toString());
}
//if DSA didnt work, then try RSA
if (!isSupportedKey) {
try {
factory = KeyFactory.getInstance("RSA");
retKey = factory.generatePublic(pubSpec);
isSupportedKey = true;
} catch (InvalidKeySpecException e) {
System.out.println("Could not create RSA Public Key: " + e.toString());
}
}
// if not DSA or RSA
if (!isSupportedKey) {
throw new InvalidKeySpecException("Unsupported key spec: Not RSA or DSA");
}
return retKey;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.