[英]Read public key from file
我正在嘗試用我的Java程序驗證文件。 我不知道我在做什么錯,我發現的所有解決方案都行不通。 這是我的代碼:
public boolean pruefeSignatur(File file, File signatur, File publicKey) {
boolean verifies = false;
try {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
// encode public key bytes
FileInputStream keyfis = new FileInputStream(publicKey);
byte [] encKey = new byte[keyfis.available()];
keyfis.read(encKey);
keyfis.close();
// key specification
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(encKey);
// conversion
KeyFactory keyFactory = KeyFactory.getInstance(pubKeySpec.getFormat());
// generate publicKey
PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
// input signature bytes
FileInputStream sigfis = new FileInputStream(signatur);
byte[] sigToVerify = new byte[sigfis.available()];
sigfis.read(sigToVerify);
sigfis.close();
// initialize the signature
Signature sig = Signature.getInstance("RSA");
sig.initVerify(pubKey);
// supply signature object with the data to be verified
FileInputStream datafis = new FileInputStream(file);
BufferedInputStream bufin = new BufferedInputStream(datafis);
byte[] buffer = new byte[1024];
int len;
while(bufin.available() != 0) {
len = bufin.read(buffer);
sig.update(buffer, 0, len);
}
bufin.close();
//verify signature
verifies = sig.verify(sigToVerify);
} catch (Exception e) {
e.printStackTrace();
}
return verifies;
}
有了這段代碼,我得到了異常:java.security.spec.InvalidKeySpecException:java.lang.ClassCastException:org.bouncycastle.asn1.DERUnknownTag無法轉換為org.bouncycastle.asn1.ASN1Object
例如,當我使用Base64時:
Base64 decoder = new Base64();
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(decoder.decode(encKey));
我收到異常:java.security.spec.InvalidKeySpecException:java.io.IOException:意外的內容結束標記
我發現的另一個解決方案是將其更改為:
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(encKey);
// conversion
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
但是然后我得到了異常:java.security.spec.InvalidKeySpecException:java.security.InvalidKeyException:無效的密鑰格式
我用Gpg4win和Kleopatra做鑰匙。
編輯:現在我沒有收到錯誤,但是函數總是返回false。 所以我不確定一切是否正確。
public boolean pruefeSignatur(File file, File signaturFile, File publicKeyFile) throws IOException {
boolean verifies = false;
FileInputStream keyfis = null;
DataInputStream keydis = null;
FileInputStream sigfis = null;
DataInputStream sigdis = null;
FileInputStream datafis = null;
DataInputStream datadis = null;
try {
// add provider
Security.addProvider(new BouncyCastleProvider());
// encode public key bytes
keyfis = new FileInputStream(publicKeyFile);
keydis = new DataInputStream(keyfis);
byte[] keyBytes = new byte[(int) publicKeyFile.length()];
keydis.readFully(keyBytes);
keyfis.close();
keydis.close();
// key specification
String modulusBase64 = new String(keyBytes);
Base64 b64 = new Base64();
String exponentBase64 = "65337"; //festgelegte Zahl http://crypto.stackexchange.com/questions/3110/impacts-of-not-using-rsa-exponent-of-65537
RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(new BigInteger(1, b64.decode(modulusBase64)), new BigInteger(1, b64.decode(exponentBase64)));
// conversion
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
// generate publicKey
PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
// read signature
sigfis = new FileInputStream(signaturFile);
sigdis = new DataInputStream(sigfis);
byte[] sigBytes = new byte[(int) signaturFile.length()];
sigdis.readFully(sigBytes);
sigfis.close();
sigdis.close();
// initialize the signature
Signature sig = Signature.getInstance("RSA");
sig.initVerify(publicKey);
// supply signature object with the data to be verified
datafis = new FileInputStream(file);
datadis = new DataInputStream(datafis);
byte[] dataBytes = new byte[(int) file.length()];
datadis.readFully(dataBytes);
/*
int len;
while(datadis.available() != 0) {
len = datadis.read(dataBytes);
sig.update(dataBytes, 0, len);
}
*/
datadis.close();
datafis.close();
sig.update(dataBytes);
//verify signature
verifies = sig.verify(sigBytes);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (keyfis != null) {
keyfis.close();
}
if (keydis != null) {
keydis.close();
}
if (sigfis != null) {
sigfis.close();
}
if (sigdis != null) {
sigdis.close();
}
if (datafis != null) {
datafis.close();
}
if (datadis != null) {
datadis.close();
}
}
return verifies;
}
最后我有一個解決方案:
InputStream inSig = PGPUtil.getDecoderStream(new FileInputStream(signaturFile));
//ArmoredInputStream inSig = new ArmoredInputStream(new FileInputStream(signaturFile));
JcaPGPObjectFactory objFactory = new JcaPGPObjectFactory(inSig);
PGPSignatureList signatureList = (PGPSignatureList) objFactory.nextObject();
PGPSignature signature = signatureList.get(0);
InputStream keyIn = PGPUtil.getDecoderStream(new FileInputStream(publicKeyFile));
//ArmoredInputStream keyIn = new ArmoredInputStream(new FileInputStream(publicKeyFile));
JcaPGPPublicKeyRingCollection pgpRing = new JcaPGPPublicKeyRingCollection(keyIn);
PGPPublicKey publicKey = pgpRing.getPublicKey(signature.getKeyID());
byte[] bytePublicKeyFingerprint = publicKey.getFingerprint();
char[] publicKeyFingerprintHexArray = org.apache.commons.codec.binary.Hex.encodeHex(bytePublicKeyFingerprint);
String publicKeyFingerprintHex = new String(publicKeyFingerprintHexArray);
signature.init(new JcaPGPContentVerifierBuilderProvider().setProvider("BC"), publicKey);
FileInputStream in = new FileInputStream(file);
byte[] byteData = new byte[(int) file.length()];
in.read(byteData);
in.close();
signature.update(byteData);
if (signature.verify() && publicKeyFingerprintHex.equals(fingerprint)) {
return true;
} else {
return false;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.