2017-08-02 34 views
0

基本上我嘗試驗證簽名,其使用OpenSSL的是這樣的:公鑰,JAVA

openssl dgst -sha256 -verify prime192v1-pub-v1.pem -signature signatureFile.bin < dataFile.bin 

...而爲了做到這一點在Android上我需要創建PublicKey對象。我正在使用的方法在線kf.generatePublic(new X509EncodedKeySpec(encoded))處拋出java.security.spec.InvalidKeySpecException: Unexpected key type

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)); 
    } 

} 

這是我如何調用該方法:

SO.getPublicKeyFromString(
      "-----BEGIN PUBLIC KEY-----\n" + 
      "MEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEXMHnQfWiM4oCaLfx296llgz7iaVv\n" + 
      "avMPppkzVNZAxtlNLhFlXnNWD0Mw9yzP8/Go\n" + 
      "-----END PUBLIC KEY-----" 
    ); 

任何人都知道我在做什麼錯?

+1

是的,它不是RSA公鑰,它是橢圓曲線(P192)公鑰。 –

+0

[無法從Java中讀取OpenSSL生成的ECDSA密鑰:InvalidKeySpecException](https://stackoverflow.com/q/42234685/608639),[如何使用海綿城堡爲比特幣曲線(secp256k1)創建ECDSA密鑰對(256位) ?](https://stackoverflow.com/q/29778852/608639),[如何將PEM編碼的橢圓曲線公鑰加載到Bouncy Castle?](https://stackoverflow.com/q/40434317/608639),[我如何從EC公鑰對象中獲取PublicKey對象?](https://stackoverflow.com/q/26159149/608639),[如何加載Elliptic Curve PEM編碼的私鑰?](https:// stackoverflow .com/q/41927859/608639)等 – jww

回答

0

我明白了。公鑰是橢圓曲線(p192)公鑰,它應該以不同的方式加載。擁有PublicKey我可以像使用openssl命令一樣驗證簽名。

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); 
    } 

}