我正在实现一个接受三项内容作为输入的接口
X509证书
使用该证书的私钥
初始哈希
必须执行以下操作:
我已经实现了以下功能来验证数字签名: -
public static boolean verifySignedHash(String X509Certificate, String hash,
String signedHash) {
boolean isVerified = false;
ByteArrayInputStream inputStream = null;
ByteArrayOutputStream outputStream = null;
ByteArrayOutputStream byo = null;
try {
outputStream = new ByteArrayOutputStream();
byte[] data = Base64.decodeBase64(X509Certificate);
/* writing decoded X509 certificate to the ByteArrayOutputStream */
outputStream.write(data);
byte[] inp = outputStream.toByteArray();
inputStream = new ByteArrayInputStream(inp);
/* Getting the certificate from the Input */
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate certs = (X509Certificate) cf
.generateCertificate(inputStream);
/* import encoded public key */
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(certs
.getPublicKey().getEncoded());
/* Instantiating KeyFactory for accesing the Keys as Object */
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
/*
* using the KeyFactory object to generate a PublicKey from the key
* specification.
*/
publickKey = keyFactory.generatePublic(pubKeySpec);
byte[] signHash = Base64.decodeBase64(signedHash);
byo = new ByteArrayOutputStream();
byo.write(signHash);
byte[] signChar = byo.toByteArray();
ByteArrayInputStream byi = new ByteArrayInputStream(signChar);
/* Next, input the signature bytes from the file specified */
byte[] sigToVerify = new byte[byi.available()];
byi.read(sigToVerify);
byi.close();
/* Instantiating Signature */
Signature signature = Signature.getInstance(certs.getSigAlgName());
/* Initializing the Public Key in Signature */
signature.initVerify(publickKey);
/* Supply the Signature Object With the Data to be Verified */
BufferedInputStream bufin = new BufferedInputStream(byi);
byte[] buffer = new byte[1024];
int len;
while (bufin.available() != 0) {
len = bufin.read(buffer);
signature.update(buffer, 0, len);
};
bufin.close();
/* Verify the Signature */
isVerified = signature.verify(sigToVerify);
} catch (Exception e) {
System.err.println("Caught exception " + e.toString());
}
return isVerified;
}
我将结果视为错误
**Am i Missing something or is this piece of code correct ?**
我非常感谢你的帮助。非常感谢。
答案 0 :(得分:1)
我已复制原始代码并将我的评论放在代码中
// X509Certificate is class name, it cannot be variable name
public static boolean verifySignedHash(String X509Certificate, String hash,
String signedHash) {
// Java is not C89 you don't have to declare variables in the beginning
// of function, this reduces readability of the code and allows misuse
boolean isVerified = false;
ByteArrayInputStream inputStream = null;
ByteArrayOutputStream outputStream = null;
ByteArrayOutputStream byo = null;
try {
outputStream = new ByteArrayOutputStream();
byte[] data = Base64.decodeBase64(X509Certificate);
/* writing decoded X509 certificate to the ByteArrayOutputStream */
outputStream.write(data);
byte[] inp = outputStream.toByteArray();
// at this point inp is the same array as data, this makes no sence
// and reduce performance
inputStream = new ByteArrayInputStream(inp);
/* Getting the certificate from the Input */
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate certs = (X509Certificate) cf
.generateCertificate(inputStream);
/* import encoded public key */
// certs.getPublicKey() returns publicKey immediately, why to do
// all these conversions?
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(certs
.getPublicKey().getEncoded());
/* Instantiating KeyFactory for accesing the Keys as Object */
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
/*
* using the KeyFactory object to generate a PublicKey from the key
* specification.
*/
publickKey = keyFactory.generatePublic(pubKeySpec);
byte[] signHash = Base64.decodeBase64(signedHash);
byo = new ByteArrayOutputStream();
byo.write(signHash);
byte[] signChar = byo.toByteArray();
// Again, signChar is the same as signHash, why would you do that?
ByteArrayInputStream byi = new ByteArrayInputStream(signChar);
/* Next, input the signature bytes from the file specified */
byte[] sigToVerify = new byte[byi.available()];
byi.read(sigToVerify);
byi.close();
// And now sigToVerify is the same as signChar and signHash.
/* Instantiating Signature */
Signature signature = Signature.getInstance(certs.getSigAlgName());
/* Initializing the Public Key in Signature */
signature.initVerify(publickKey);
/* Supply the Signature Object With the Data to be Verified */
// byi is already closed, you will get java.io.IOException: Stream closed
BufferedInputStream bufin = new BufferedInputStream(byi);
byte[] buffer = new byte[1024];
int len;
while (bufin.available() != 0) {
len = bufin.read(buffer);
signature.update(buffer, 0, len);
// Any way bufin contained signature, while you need feed
// plaintext to signature.update()
// I could assume unused parameter hash has something to do
// with plaintext
};
bufin.close();
/* Verify the Signature */
isVerified = signature.verify(sigToVerify);
} catch (Exception e) {
System.err.println("Caught exception " + e.toString());
}
return isVerified;
}