I am trying to understand what the Java class java.security.Signature does. If I calculate the digest of the SHA1 message and then encrypt this digest using RSA, I get a different result to ask the Signature class to sign the same:
// 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));
Results (for example):
Input: This is a signed message.
Digest: 62b0a9ef15461c82766fb5bdaae9edbe4ac2e067
Ciphertext: 057dc0d2f7f54acc95d3cf5cba9f944619394711003bdd12 ...
Signature: 7177c74bbbbb871cc0af92e30d2808ebae146f25d3fd8ba1622 ...
I should have a fundamental misunderstanding of what the signature does - I followed it up and it seems to cause the MessageDigest object to be updated, with the algorithm set to SHA1, as you would expect, then getting the digest, then do the encryption. What makes the results different?
EDIT:
Leonid made me check if the signature scheme should do what I think. There are two types of signatures defined in the
RFC :
the first one (PKCS1) is the one I described above. It uses a hash function to create a digest, and then encrypts the result with a private key.
The second algorithm uses a random salt value and is safer, but not deterministic. The signature obtained from the above code does not change if the same key is reused, so I donโt think it could be PSS.
EDIT:
Here is the bytes2string method that I used:
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(); }
java cryptography encryption rsa digital-signature
Mike Houston Feb 06 '09 at 16:51 2009-02-06 16:51
source share