J'essaie de comprendre ce que le Java java.de sécurité.La Signature de la classe. Si je calcule une SHA1 résumé de message, puis crypter, qui digèrent à l'aide de RSA, j'obtiens un résultat différent à demander à la Signature de la classe à signer la même chose:
// Generate new key
KeyPair keyPair = KeyPairGenerator.getInstance("RSA").generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
String plaintext = "This is the message being signed";
// Compute signature
Signature instance = Signature.getInstance("SHA1withRSA");
instance.initSign(privateKey);
instance.update((plaintext).getBytes());
byte[] signature = instance.sign();
// Compute digest
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
byte[] digest = sha1.digest((plaintext).getBytes());
// Encrypt digest
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] cipherText = cipher.doFinal(digest);
// Display results
System.out.println("Input data: " + plaintext);
System.out.println("Digest: " + bytes2String(digest));
System.out.println("Cipher text: " + bytes2String(cipherText));
System.out.println("Signature: " + bytes2String(signature));
Résultats dans (par exemple):
Données d'entrée: C'est le message en cours de signature
Digest: 62b0a9ef15461c82766fb5bdaae9edbe4ac2e067
Le texte chiffré: 057dc0d2f7f54acc95d3cf5cba9f944619394711003bdd12...
Signature: 7177c74bbbb871cc0af92e30d2808ebae146f25d3fd8ba1622...
Je dois avoir une incompréhension fondamentale de ce que la Signature est en train de faire - j'ai tracé à travers elle, et elle semble être l'appel de mise à jour sur un MessageDigest objet, avec l'algorithme défini à SHA1 comme je l'espère, par l'obtention de l'empreinte, puis de faire le cryptage. Ce qui rend les résultats diffèrent-ils?
EDIT:
Leonidas m'a fait vérifier si la signature régime est censé faire ce que je pense. Il existe deux types de signature définie dans la RFC:
La première de ces (PKCS1) est celui que j'ai décrit ci-dessus. Il utilise une fonction de hachage à créer un digest, et crypte le résultat avec une clé privée.
Le deuxième algorithme utilise un hasard sel de la valeur, et est plus sûre, mais non-déterministe. La signature produite à partir du code ci-dessus ne change pas si la même clé est utilisée à plusieurs reprises, donc je ne pense pas qu'il se PSS.
EDIT:
Voici l' bytes2string
méthode que j'utilisais:
private static String bytes2String(byte[] bytes) {
StringBuilder string = new StringBuilder();
for (byte b : bytes) {
String hexString = Integer.toHexString(0x00FF & b);
string.append(hexString.length() == 1 ? "0" + hexString : hexString);
}
return string.toString();
}