问题描述
基本上我正在尝试验证使用openssl的签名如下:
Basically I'm trying to verify signature which using openssl looks like this:
openssl dgst -sha256 -verify prime192v1-pub-v1.pem -signature signatureFile.bin < dataFile.bin
...为了在android上执行此操作,我需要创建 PublicKey
对象。我正在使用的方法抛出 java.security.spec.InvalidKeySpecException:意外的密钥类型
在行 kf.generatePublic(new X509EncodedKeySpec(encoded))
。
... and in order to do that on android I need to create PublicKey
object. The method that I'm using throws java.security.spec.InvalidKeySpecException: Unexpected key type
at line kf.generatePublic(new X509EncodedKeySpec(encoded))
.
import org.spongycastle.util.encoders.Base64;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.X509EncodedKeySpec;
public class SO {
public static PublicKey getPublicKeyFromString(String key) throws IOException, GeneralSecurityException {
String publicKeyPEM = key;
publicKeyPEM = publicKeyPEM.replace("-----BEGIN PUBLIC KEY-----\n", "");
publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", "");
byte[] encoded = Base64.decode(publicKeyPEM);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(new X509EncodedKeySpec(encoded));
}
}
这就是我调用方法的方法:
This is how I call the method:
SO.getPublicKeyFromString(
"-----BEGIN PUBLIC KEY-----\n" +
"MEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEXMHnQfWiM4oCaLfx296llgz7iaVv\n" +
"avMPppkzVNZAxtlNLhFlXnNWD0Mw9yzP8/Go\n" +
"-----END PUBLIC KEY-----"
);
任何人都知道我做错了什么?
Anyone knows what I'm doing wrong?
推荐答案
我搞定了。公钥是椭圆曲线(p192)公钥,应加载不同。拥有 PublicKey
我能够像使用openssl命令一样验证签名。
I got it working. The public key is elliptic curve (p192) public key and it should be loaded differently. Having PublicKey
I was able to verify signature the same way as using openssl command.
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.io.Reader;
import java.io.StringReader;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.Security;
import java.security.Signature;
import java.security.spec.X509EncodedKeySpec;
public class SO {
public PublicKey getPublicKey() throws Exception {
Security.addProvider(new BouncyCastleProvider());
Reader rdr = new StringReader(
"-----BEGIN PUBLIC KEY-----\n" +
"MEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEXMHnQfWiM4oCaLfx296llgz7iaVv\n" +
"avMPppkzVNZAxtlNLhFlXnNWD0Mw9yzP8/Go\n" +
"-----END PUBLIC KEY-----\n"
); // or from file etc.
org.bouncycastle.util.io.pem.PemObject spki = new org.bouncycastle.util.io.pem.PemReader(rdr).readPemObject();
PublicKey key = KeyFactory.getInstance("EC", "BC").generatePublic(new X509EncodedKeySpec(spki.getContent()));
return key;
}
public static boolean verify(byte[] data, byte[] signatureBytes, PublicKey publicKey) throws Exception {
Signature signature = Signature.getInstance("SHA256withECDSA", "BC");
signature.initVerify(publicKey);
signature.update(data);
return signature.verify(signatureBytes);
}
}
这篇关于来自android,java上的PEM文件的PublicKey的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!