signature.verify() 在 java 中返回 false
signature.verify() is returning false in java
首先,我看到其他帖子也有这个问题,但没有人遇到和我一样的问题,即 signature.verify()
意外返回 false
。
这是我的代码:
private static String encriptar(String xmlSolicitud, PrivateKey privateKey)
throws Exception {
Signature signature=Signature.getInstance("SHA1withRSA");
signature.initSign(privateKey);
signature.update(xmlSolicitud.getBytes(Charset.forName("UTF-8")));
byte[] signatureValue = signature.sign();
String response = Base64.encode(signatureValue);
signature.initVerify(keyReader.publicKeyRead(Reference.rutaPublicKeyTest));
System.out.println(signature.verify(signatureValue));
return response;
}
下面是我读取密钥的方式(如果需要):
public static PrivateKey privateKeyRead(String filename)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
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();
PKCS8EncodedKeySpec spec =
new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(spec);
}
public static PublicKey publicKeyRead(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);
}
签名状态在您调用 sign
后重置。根据 documentation:
A call to this method resets this signature object to the state it was
in when previously initialized for signing via a call to
initSign(PrivateKey)
. That is, the object is reset and available to
generate another signature from the same signer, if desired, via new
calls to update
and sign
.
您需要使用已签名的字节再次更新签名:
private static String encriptar(String xmlSolicitud, PrivateKey privateKey)
throws Exception {
Signature signature=Signature.getInstance("SHA1withRSA");
signature.initSign(privateKey);
signature.update(xmlSolicitud.getBytes(Charset.forName("UTF-8")));
byte[] signatureValue = signature.sign();
String response = Base64.encode(signatureValue);
signature.initVerify(keyReader.publicKeyRead(Reference.rutaPublicKeyTest));
signature.update(xmlSolicitud.getBytes(Charset.forName("UTF-8"))); // <-- Here
System.out.println(signature.verify(signatureValue)); // <-- Will print true
return response;
}
附带说明一下,您似乎正在签署 XML 内容。使用 XML signatures 以避免被规范化问题绊倒可能是明智的。
首先,我看到其他帖子也有这个问题,但没有人遇到和我一样的问题,即 signature.verify()
意外返回 false
。
这是我的代码:
private static String encriptar(String xmlSolicitud, PrivateKey privateKey)
throws Exception {
Signature signature=Signature.getInstance("SHA1withRSA");
signature.initSign(privateKey);
signature.update(xmlSolicitud.getBytes(Charset.forName("UTF-8")));
byte[] signatureValue = signature.sign();
String response = Base64.encode(signatureValue);
signature.initVerify(keyReader.publicKeyRead(Reference.rutaPublicKeyTest));
System.out.println(signature.verify(signatureValue));
return response;
}
下面是我读取密钥的方式(如果需要):
public static PrivateKey privateKeyRead(String filename)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
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();
PKCS8EncodedKeySpec spec =
new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(spec);
}
public static PublicKey publicKeyRead(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);
}
签名状态在您调用 sign
后重置。根据 documentation:
A call to this method resets this signature object to the state it was in when previously initialized for signing via a call to
initSign(PrivateKey)
. That is, the object is reset and available to generate another signature from the same signer, if desired, via new calls toupdate
andsign
.
您需要使用已签名的字节再次更新签名:
private static String encriptar(String xmlSolicitud, PrivateKey privateKey)
throws Exception {
Signature signature=Signature.getInstance("SHA1withRSA");
signature.initSign(privateKey);
signature.update(xmlSolicitud.getBytes(Charset.forName("UTF-8")));
byte[] signatureValue = signature.sign();
String response = Base64.encode(signatureValue);
signature.initVerify(keyReader.publicKeyRead(Reference.rutaPublicKeyTest));
signature.update(xmlSolicitud.getBytes(Charset.forName("UTF-8"))); // <-- Here
System.out.println(signature.verify(signatureValue)); // <-- Will print true
return response;
}
附带说明一下,您似乎正在签署 XML 内容。使用 XML signatures 以避免被规范化问题绊倒可能是明智的。