2010-06-30 230 views
3
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; 
} 

此代碼始終返回false。我不確定該從哪裏出發。signature.verify()總是返回False

+1

您正在驗證什麼都沒有。如果您的簽名也是爲空數據生成的,它只會返回true。 – 2010-06-30 17:00:47

+0

我以爲我正在驗證它對sigBytes。你知道我會如何解決這個問題嗎? – Jimmy 2010-06-30 17:07:20

回答

3

我認爲問題在於你實際上沒有給它一個消息來驗證。

RSA簽名首先對消息進行散列(即「SHA1withRSA」中的「SHA1」),然後對其執行trapdoor operation。除非您知道一些祕密信息(RSA私鑰),否則這是一個方向易於執行而另一方向很難執行的操作。

要驗證,首先要反轉數學變換(因爲它在一個方向上很容易),然後將簽名中嵌入的哈希與剛剛計算的消息的哈希進行比較。簽名本身不包含該消息;要驗證簽名,您需要簽名和已簽名的消息。

API級別,看起來Signature班級希望您撥打update並附上此簽名用於的消息內容。如果沒有這個,它可能會將散列與空字符串的散列進行比較,所以除非最初簽名的消息也是空字符串,否則簽名實際上是無效的。

+0

在我的例子中signedMessage是加密文本(用戶id +公司id)。 – Jimmy 2010-06-30 17:04:20

+1

正確 - 您必須通過更新提供您簽名到Signature類的數據。你實際上並沒有對任何東西進行驗證(這暗示你正在驗證它是否對空字符串進行驗證,而不是對你簽名的內容進行驗證)。 – 2010-06-30 18:25:57

7

可以註冊的消息,你應該有一些像這樣的代碼:

Signature signature = Signature.getInstance("SHA1withRSA"); 
signature.initSign(privKey); 
signature.update(message); 
byte[] signatureValue = signature.sign(); 

注意字節數組命名signatureValue。這是數據上的實際簽名。這就是你應該提供給verify()-方法。應在撥打update()-方法時提供已簽名的消息。 I.e .:

Signature signature = Signature.getInstance("SHA1withRSA"); 
signature.initVerify(pubKey); 
signature.update(message); 
bool ok = signature.verify(signatureValue); 
1

你說得對,謝謝傑克。以下方法完美工作(即使使用.NET創建的密鑰)!我希望這可以幫助別人。

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