Java signature.verify()始终返回False publicstaticvoidmain(字符串[]args){ 试一试{ String mod=“Q0awozeuj0vvvkoksdqsctj3qegodomq4sar02xmyirwldzrnhwfzaicwt2muay3x6s3zfufofxorvbltrro3f9z6r8/jjimv7wjkevbfc5gncwgr0c3av9gmf6i19jtff1sxb26imemeosnaacenajh91zboaw7zih+qk=”; 字符串exp=“AQAB”; byte[]modulesBytes=Base64.decodeBase64(mod.getBytes(“UTF-8”); byte[]exponentBytes=Base64.decodeBase64(exp.getBytes(“UTF-8”); 字符串签名消息=“3753E672CFB21E3C182EF2DF51F1F1F19EDEFB63432ED338A47251326CCC14AA63883E910A140CF313754EBC6425AAD434E309307CC882DA6CD4A4F9F40BD14A9823ACA145E5FFC97CD63DBB5925C0492416DFD7D74DEEF7055065210A841793FE315DFF5A44AFC1522AAFDC2F7E51CA2BF79DFB086D210168DD”; BigInteger模数=新的BigInteger(1,ModulesBytes); BigInteger指数=新的BigInteger(1,指数字节); RSAPublicKeySpec rsaPubKey=新的RSAPublicKeySpec(模数、指数); KeyFactory事实=KeyFactory.getInstance(“RSA”); PublicKey pubKey=fact.generatePublic(rsaPubKey); Signature-Signature=Signature.getInstance(“SHA1withRSA”); byte[]sigBytes=hexStringToByteArray(signedMessage); signature.initVerify(pubKey); System.out.println(signature.verify(sigBytes)); }捕获(例外e){ System.out.println(“错误:+e.toString()); } } 私有静态字节[]hexStringToByteArray(最终字符串编码){ 如果((encoded.length()%2)!=0) 抛出新的IllegalArgumentException(“输入字符串必须包含偶数个字符”); 最终字节结果[]=新字节[encoded.length()/2]; final char enc[]=encoded.toCharArray(); 对于(int i=0;i
此代码始终返回false。我不知道该从这里走到哪里。我认为问题在于您实际上没有给它发送消息以进行验证 RSA签名的工作原理是首先对消息进行散列(即“SHA1withRSA”中的“SHA1”),然后对其执行散列。这是一个操作,在一个方向很容易,在另一个方向很难,除非你知道一些秘密信息(RSA私钥) 为了验证,您首先反转数学变换(因为它在一个方向上很容易),然后将嵌入签名中的哈希值与刚才计算的消息哈希值进行比较。签名本身不包含信息;要验证签名,您需要签名和已签名的邮件Java signature.verify()始终返回False publicstaticvoidmain(字符串[]args){ 试一试{ String mod=“Q0awozeuj0vvvkoksdqsctj3qegodomq4sar02xmyirwldzrnhwfzaicwt2muay3x6s3zfufofxorvbltrro3f9z6r8/jjimv7wjkevbfc5gncwgr0c3av9gmf6i19jtff1sxb26imemeosnaacenajh91zboaw7zih+qk=”; 字符串exp=“AQAB”; byte[]modulesBytes=Base64.decodeBase64(mod.getBytes(“UTF-8”); byte[]exponentBytes=Base64.decodeBase64(exp.getBytes(“UTF-8”); 字符串签名消息=“3753E672CFB21E3C182EF2DF51F1F1F19EDEFB63432ED338A47251326CCC14AA63883E910A140CF313754EBC6425AAD434E309307CC882DA6CD4A4F9F40BD14A9823ACA145E5FFC97CD63DBB5925C0492416DFD7D74DEEF7055065210A841793FE315DFF5A44AFC1522AAFDC2F7E51CA2BF79DFB086D210168DD”; BigInteger模数=新的BigInteger(1,ModulesBytes); BigInteger指数=新的BigInteger(1,指数字节); RSAPublicKeySpec rsaPubKey=新的RSAPublicKeySpec(模数、指数); KeyFactory事实=KeyFactory.getInstance(“RSA”); PublicKey pubKey=fact.generatePublic(rsaPubKey); Signature-Signature=Signature.getInstance(“SHA1withRSA”); byte[]sigBytes=hexStringToByteArray(signedMessage); signature.initVerify(pubKey); System.out.println(signature.verify(sigBytes)); }捕获(例外e){ System.out.println(“错误:+e.toString()); } } 私有静态字节[]hexStringToByteArray(最终字符串编码){ 如果((encoded.length()%2)!=0) 抛出新的IllegalArgumentException(“输入字符串必须包含偶数个字符”); 最终字节结果[]=新字节[encoded.length()/2]; final char enc[]=encoded.toCharArray(); 对于(int i=0;i,java,encryption,private,public,verify,Java,Encryption,Private,Public,Verify,此代码始终返回false。我不知道该从这里走到哪里。我认为问题在于您实际上没有给它发送消息以进行验证 RSA签名的工作原理是首先对消息进行散列(即“SHA1withRSA”中的“SHA1”),然后对其执行散列。这是一个操作,在一个方向很容易,在另一个方向很难,除非你知道一些秘密信息(RSA私钥) 为了验证,您首先反转数学变换(因为它在一个方向上很容易),然后将嵌入签名中的哈希值与刚才计算的消息哈希值进行比较。签名本身不包含信息;要验证签名,您需要签名和已签名的邮件 在某种程度上,似乎签名类希望您
在某种程度上,似乎
签名
类希望您调用更新
,其中包含该签名所针对的消息的内容。如果没有这一点,它可能会将散列与空字符串的散列进行比较,因此,除非最初签名的消息也是空字符串,否则签名实际上是无效的。在签名消息的地方,应该有如下代码:
public static void main(String[] args) {
try{
String mod = "q0AwozeUj0VVkoksDQSCTj3QEgODomq4sAr02xMyIrWldZrNHhWfZAIcWt2MuAY3X6S3ZVUfOFXOrVbltRrO3F9Z6R8/jJIMv7wjkeVBFC5gncwGR0C3aV9gmF6II19jTKfF1sxb26iMEMAlMEOSnAAceNaJH91zBoaW7ZIh+qk=";
String exp = "AQAB";
byte[] modulusBytes = Base64.decodeBase64(mod.getBytes("UTF-8"));
byte[] exponentBytes = Base64.decodeBase64(exp.getBytes("UTF-8"));
String signedMessage = "3753e672cfb21e3c182ef2df51f19edeffb63432ed338a47251326ccc14aa63883e910a140cf313754ebc6425aad434e309307cc882da6cd4a4f9f40bd14a9823aca145e5ffc97cd63dbb5925c049282416bdfd7d74ddeef7055065210a841793fe315dff5a44af19c1522daafdc2f7e61ce5a2b42ebf79dfb086e6d210168dd";
BigInteger modulus = new BigInteger(1, modulusBytes );
BigInteger exponent = new BigInteger(1, exponentBytes);
RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(rsaPubKey);
Signature signature = Signature.getInstance("SHA1withRSA");
byte[] sigBytes = hexStringToByteArray(signedMessage);
signature.initVerify(pubKey);
System.out.println(signature.verify(sigBytes));
}catch(Exception e){
System.out.println("Error: " + e.toString());
}
}
private static byte[] hexStringToByteArray(final String encoded) {
if ((encoded.length() % 2) != 0)
throw new IllegalArgumentException("Input string must contain an even number of characters");
final byte result[] = new byte[encoded.length()/2];
final char enc[] = encoded.toCharArray();
for (int i = 0; i < enc.length; i += 2) {
StringBuilder curr = new StringBuilder(2);
curr.append(enc[i]).append(enc[i + 1]);
result[i/2] = (byte) Integer.parseInt(curr.toString(), 16);
}
return result;
}
注意名为signatureValue
的字节数组。这是数据上的实际签名。这就是您应该为verify()
-方法提供的内容。签名的消息应该在调用update()
-方法时提供。即:
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initSign(privKey);
signature.update(message);
byte[] signatureValue = signature.sign();
你说得对,谢谢,杰克。下面的方法可以完美地工作(即使使用.NET中创建的密钥)!我希望这能帮助别人
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initVerify(pubKey);
signature.update(message);
bool ok = signature.verify(signatureValue);
你什么都没有核实。只有在为空数据生成签名时,才会返回true。我以为我是在根据sigBytes验证它。你知道我将如何解决这个问题吗?在我的示例中,signedMessage是加密文本(用户id+公司id)。对-你必须通过更新向Signature类提供你签名的数据。实际上,您没有根据任何内容验证签名(这意味着您是根据空字符串验证签名,而不是根据您所签名的内容)。
public static void main(String[] args) {
try{
String userID = "189711";
String companyCode = "ILIKEPIZZA";
String combine = userID + "." + companyCode;
String mod = "q0AwozeUj0VVkoksDQSCTj3QEgODomq4sAr02xMyIrWldZrNHhWfZAIcWt2MuAY3X6S3ZVUfOFXOrVbltRrO3F9Z6R8/jJIMv7wjkeVBFC5gncwGR0C3aV9gmF6II19jTKfF1sxb26iMEMAlMEOSnAAceNaJH91zBoaW7ZIh+qk=";
String exp = "AQAB";
byte[] modulusBytes = Base64.decodeBase64(mod.getBytes("UTF-8"));
byte[] exponentBytes = Base64.decodeBase64(exp.getBytes("UTF-8"));
String sign = "3753e672cfb21e3c182ef2df51f19edeffb63432ed338a47251326ccc14aa63883e910a140cf313754ebc6425aad434e309307cc882da6cd4a4f9f40bd14a9823aca145e5ffc97cd63dbb5925c049282416bdfd7d74ddeef7055065210a841793fe315dff5a44af19c1522daafdc2f7e61ce5a2b42ebf79dfb086e6d210168dd";
BigInteger modulus = new BigInteger(1, modulusBytes );
BigInteger exponent = new BigInteger(1, exponentBytes);
RSAPublicKeySpec rsaPubKey = new RSAPublicKeySpec(modulus, exponent);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(rsaPubKey);
Signature signature = Signature.getInstance("SHA1withRSA");
byte[] sigBytes = hexStringToByteArray(sign);
signature.initVerify(pubKey);
signature.update(combine.getBytes("UTF-8"));
System.out.println(signature.verify(sigBytes));
}catch(Exception e){
System.out.println("Error: " + e.toString());
}
}