2010-06-30 5 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; 
} 

Ce code renvoie toujours false. Je ne sais pas où aller à partir d'ici.signature.verify() Renvoie toujours Faux

+1

Vous vérifiez contre rien. Cela ne retournera vrai que si votre signature est également générée pour des données vides. –

+0

Je pensais que je le vérifiais contre les sigBytes. Sais-tu comment je réparerais ça? – Jimmy

Répondre

3

Je pense que le problème est que vous ne lui donnez pas un message à vérifier. Une signature RSA fonctionne en hachant d'abord le message (c'est le "SHA1" dans "SHA1withRSA"), puis en y exécutant trapdoor operation. C'est une opération qui est facile à faire dans une direction et dure dans l'autre direction, sauf si vous connaissez des informations secrètes (la clé privée RSA). Pour vérifier, vous devez d'abord inverser la transformation mathématique (car il est facile dans une direction), puis comparer le hachage qui est incorporé dans la signature avec le hachage du message que vous venez de calculer. La signature ne contient pas en soi le message; Pour vérifier une signature, vous avez besoin à la fois de la signature et du message signé.

À un niveau API, il semble que la classe Signature s'attend à ce que vous appeliez update avec le contenu du message pour lequel cette signature était destinée. Sans cela, c'est probablement en comparant le hachage avec le hachage d'une chaîne vide, donc à moins que votre message initialement signé ne soit également une chaîne vide, la signature n'est en fait pas valide.

+0

signedMessage dans mon exemple est un texte chiffré (ID utilisateur + ID société). – Jimmy

+1

Droit - vous devez fournir les données que vous avez signées à la classe Signature via la mise à jour. Vous n'êtes pas en train de vérifier la signature contre quoi que ce soit (ce qui signifie implicitement que vous la vérifiez par rapport à la chaîne vide, pas par rapport à ce que vous avez signé). –

7

Si vous signez le message que vous devez avoir un code comme ceci:

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

Notez l'octet tableau nommé signatureValue. C'est la signature réelle sur les données. C'est ce que vous devez fournir à la méthode verify(). Le message signé doit être fourni lors d'un appel à la méthode update(). I.e .:

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

Vous aviez raison, merci Jack. La méthode ci-dessous fonctionne parfaitement (même avec une clé créée en .NET)! J'espère que cela aide les autres.

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