我已经创建了公钥和私钥。从php代码生成的公钥和私钥:
<?php
require __DIR__ . '/vendor/autoload.php';
use phpseclib\Crypt\RSA;
$rsa = new RSA();
extract($rsa->createKey());
$rsa->setPrivateKeyFormat(RSA::PRIVATE_FORMAT_PKCS8);
$rsa->setPublicKeyFormat(RSA::PUBLIC_FORMAT_PKCS8);
file_put_contents("privateKey.pem",$privatekey);
file_put_contents("publicKey.pem", $publickey);
读取这些键的Java源代码:
import java.io.*;
import java.security.*;
import java.security.spec.*;
public class PublicKeyReader {
public static PublicKey get(String filename)
throws Exception {
File f = new File(filename);
FileInputStream fis = new FileInputStream(f);
DataInputStream dis = new DataInputStream(fis);
byte[] keyBytes = new byte[(int)f.length()];
dis.readFully(keyBytes);
dis.close();
X509EncodedKeySpec spec =
new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
public static void main (String [] args) throws Exception {
PublicKeyReader publicKeyReader = new PublicKeyReader();
PublicKey publicKey = publicKeyReader.get("key/testPub.pem");
System.out.println(publicKey);
}
}
它产生java.security.InvalidKeyException: invalid key format.
对此需要帮助。预先感谢。
答案 0 :(得分:1)
首先,如注释中所述,没有诸如PKCS#8公钥之类的东西。这意味着PHP库不知道它在说什么。相反,如果neubert是正确的,您似乎会得到的是为X.509证书定义的结构,称为X509EncodedKeySpec
。并且在Java代码中,您确实确实试图使用它来读取公共密钥。
但是,您忘记的是X509EncodedKeySpec
是二进制格式,在ASN.1 DER中指定。您收到的是使用ASCII装甲的PEM编码的密钥。换句话说,二进制文件已编码为base64,并且添加了页眉和页脚行。这样做是为了使其与诸如邮件(Privacy Enhanced Mail或PEM)之类的文本界面兼容。
所以您要做的是卸下盔甲。最好使用PEM阅读器(例如Bouncy Castle提供的阅读器)来完成此操作。
PemReader reader = new PemReader(new FileReader("spki.pem"));
PemObject readPemObject = reader.readPemObject();
String type = readPemObject.getType();
byte[] subjectPublicKey = readPemObject.getContent();
System.out.println(type);
X509EncodedKeySpec spec = new X509EncodedKeySpec(subjectPublicKey);
KeyFactory kf = KeyFactory.getInstance("RSA");
RSAPublicKey pubKey = (RSAPublicKey) kf.generatePublic(spec);
System.out.println(pubKey);
可打印
PUBLIC KEY
之后
Sun RSA public key, 1024 bits
params: null
modulus: 119445732379544598056145200053932732877863846799652384989588303737527328743970559883211146487286317168142202446955508902936035124709397221178664495721428029984726868375359168203283442617134197706515425366188396513684446494070223079865755643116690165578452542158755074958452695530623055205290232290667934914919
public exponent: 65537
对于怀疑论者-hi neubert ;)-这是X.509 specification中SubjectPublicKeyInfo的定义:
SubjectPublicKeyInfo ::= SEQUENCE {
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING }
其中subjectPublicKey
包含PKCS#1格式的编码公共密钥-当然,对于RSA公共密钥。
here是Neubert密钥的解码版本,因此您可以进行比较。 Java中解析的密钥是相同的密钥。