Chapter 2 digital signature algorithm-RSA, digital signature-rsa
Note: In this section, refer
- Java encryption and decryption art (2nd edition) Chapter 9th "message digest algorithm with key-digital signature algorithm"
- Chapter 3rd "Internet security architecture" of "Design and Practice of large-scale distributed website architecture"
14.1 Digital Signature Algorithm
Features:
- Combination of asymmetric encryption algorithm and message digest algorithm
- Anti-denial, authentication of data sources, and prevention of Data tampering (for specific meanings and practices, see the following process and analogy)
- Private Key Encryption (signature) and Public Key decryption (verification)
Process:
1) The message sender generates a key pair (Private Key + Public Key) and then sends the public key to the message receiver.
2) The message sender uses the message digest algorithm to encrypt the original text (the encrypted ciphertext is called the Digest)
3) The message sender encrypts the summary with the private key to obtain the ciphertext. This process is called signature processing and the obtained ciphertext is called signature (note that this signature is a term)
4) The message sender sends the original text and ciphertext to the message receiver.
5) The message receiver decrypts the ciphertext (Signature) using the public key to obtain the abstract value content1.
6) The Message Receiver encrypts the original text using the same message digest algorithm as the message sender to obtain the abstract value content2.
7) Check whether content1 is equal to content2. If they are equal, the message is not tampered (Message Integrity), It also indicates that the message is from the above message sender (because others cannot forge the signature, This completes"Anti-denialAndAuthenticate the message source")
Analogy:
Handwritten Signature:
- Zhang San signed his name in the contract, so that he would not be able to deny his contract (Anti-denial)
- After James signed the contract, if the contract content changes, the signature will be deemed invalid at this time.
- Of course, through the signature of Michael Jacob on the contract, we can know that the source of the signature is Michael Jacob (the authentication data source)
Common digital signature algorithms:
- RSA (a classic digital signature algorithm and the most common digital signature algorithm)
- DSA (the basis of subsequent digital signature algorithms)
- ECDSA (combination of ECC and DSA, which is faster, higher, and shorter than other digital signature algorithms, but not widely used in RSA)
14.2. RSA
Common algorithms:
- MD5WithRSA (JDK6)
- SHA1WithRSA (JDK6)
- SHA256WithRSA (> = JDK1.6.45, Bouncy Castle --> BC for short)
Note: In the book "Java encryption and decryption (version 2)", JDK 6 does not support SHA256WithRSA, but it is supported by my own test 1.6.45.
Implementation Method: (refer to the above three rows)
14.2.1 MD5WithRSA, SHA1WithRSA, or SHA256WithRSA Algorithm Based on JDK 6
1 package com. uti. rsa. digital; 2 3 import java. io. unsupportedEncodingException; 4 import java. security. invalidKeyException; 5 import java. security. keyFactory; 6 import java. security. keyPair; 7 import java. security. keyPairGenerator; 8 import java. security. noSuchAlgorithmException; 9 import java. security. privateKey; 10 import java. security. publicKey; 11 import java. security. signature; 12 import java. Security. signatureException; 13 import java. security. spec. invalidKeySpecException; 14 import java. security. spec. PKCS8EncodedKeySpec; 15 import java. security. spec. x509EncodedKeySpec; 16 17 import org. apache. commons. codec. binary. base64; 18 19/** 20 * BC-based RSA Digital Signature Algorithm 21 */22 public class RSACoderBC {23 private static final String ENCODING = "UTF-8 "; 24 private static final String KEY_ALGORITHM = "R SA "; // asymmetric encryption key algorithm 25 private static final String SIGNATURE_ALGORITHM =" MD5withRSA "; // specify the digital signature algorithm (which can be replaced by SHA1withRSA or SHA256withRSA) 26 private static final int KEY_SIZE = 512; // asymmetric key length (512 ~ 64 integer times between 1024) 27 28/** 29 * generate the sender key pair 30 */31 public static KeyPair initKey () throws NoSuchAlgorithmException {32 KeyPairGenerator keyPairGenerator = KeyPairGenerator. getInstance (KEY_ALGORITHM); // key pair generator 33 keyPairGenerator. initialize (KEY_SIZE); // specify the key length 34 KeyPair keyPair = keyPairGenerator. generateKeyPair (); // generate the key pair 35 return keyPair; 36} 37 38/** 39 * restore the public key 40 * @ param pubKey binary Public Key 41 */42 publ Ic static PublicKey toPublicKey (byte [] pubKey) throws NoSuchAlgorithmException, 43 InvalidKeySpecException {44 KeyFactory keyFactory = KeyFactory. getInstance (KEY_ALGORITHM); // key factory 45 return keyFactory. generatePublic (new X509EncodedKeySpec (pubKey )); // restore public key 46} 47 48/** 49 * restore private key 50 * @ param priKey binary Private Key 51 */52 public static PrivateKey toPrivateKey (byte [] priKey) throws NoSuchAlgorithmException, 53 InvalidKeySpecException {54 KeyFactory keyFactory = KeyFactory. getInstance (KEY_ALGORITHM); // key factory 55 return keyFactory. generatePrivate (new PKCS8EncodedKeySpec (priKey); // restore private key 56} 57 58/*** 59 * private key encryption (Signature) 60 * @ param data to be encrypted 61 * @ param keyByte Private Key 62 */63 public static byte [] encryptPriKey (String data, byte [] keyByte) throws NoSuchAlgorithmException, 64 InvalidKeySpecException, 65 InvalidKeyE Xception, 66 SignatureException, 67 UnsupportedEncodingException {68 PrivateKey priKey = toPrivateKey (keyByte); // restore private key 69 70 Signature signature = Signature. getInstance (SIGNATURE_ALGORITHM); 71 signature. initSign (priKey); 72 signature. update (data. getBytes (ENCODING); 73 74 return signature. sign (); 75} 76 77/** 78 * Public Key decryption (verification) 79 * @ param data original (data to be encrypted has become "data to be verified ") 80 * @ param keyByte Public Key 81 * @ param Sign ciphertext (also known as "signature") 82 */83 public static boolean decryptPubKey (String data, byte [] keyByte, byte [] sign) throws NoSuchAlgorithmException, 84 InvalidKeySpecException, 85 InvalidKeyException, 86 SignatureException, 87 UnsupportedEncodingException {88 PublicKey pubKey = toPublicKey (keyByte); // restore the public key 89 90 Signature signature = Signature. getInstance (SIGNATURE_ALGORITHM); 91 signature. initVerify (pubKey); 92 signature. update (data. getBytes (ENCODING); 93 94 return signature. verify (sign); 95} 96 97/** 98 * Get public Key 99 */100 public static byte [] getPublicKey (KeyPair keyPair) {101 return keyPair. getPublic (). getEncoded (); 102} 103 104/** 105 * Get private key 106 */107 public static byte [] getPrivateKey (KeyPair keyPair) {108 return keyPair. getPrivate (). getEncoded (); 109} 110 111/** 112 * test 113 */114 public static void Main (String [] args) throws failed, 115 InvalidKeyException, 116 InvalidKeySpecException, 117 SignatureException, 118 UnsupportedEncodingException {119 byte [] pubKey1; // Party A's public key 120 byte [] priKey1; // Party A's private key 121 122/********************* test whether the above two keys can be correctly generated ** * *****************/123 KeyPair keyPair1 = RSACoderBC. initKey (); // generate Party A's key pair 124 pubKey1 = RSACoderBC. getPublicKey (keyPair1); 125 priKey1 = R SACoderBC. getPrivateKey (keyPair1); 126 127 System. out. println ("Party A's public key pubKey1 -->" + Base64.encodeBase64String (pubKey1) + "@ pubKey1.length -->" + pubKey1.length); 128 System. out. println ("Party A's private key priKey1 -->" + Base64.encodeBase64String (priKey1) + "@ priKey1.length -->" + priKey1.length ); 129 130/********************* test that party a uses the private key to encrypt data and send it to Party B, party B uses the public key to decrypt data ******************/131 System. out. println ("Party A --> Party B"); 132 String data = "Find Good girl! Hello, Kid. "; 133 byte [] encodeStr = RSACoderBC. encryptPriKey (data, priKey1); // encrypt (Signature) 134 System. out. println ("data encrypted by Party A -->" + Base64.encodeBase64String (encodeStr) + "@ encodeStr. length --> "+ encodeStr. length); 135 boolean decodeStr = RSACoderBC. decryptPubKey (data, pubKey1, encodeStr); 136 System. out. println ("Party B's test results -->" + decodeStr); 137} 138}View Code
Note:
- The code is basically the same as the RSA asymmetric encryption algorithm (See Chapter 12th). It only changes the encryption algorithm of the private key encryption and Public Key decryption to the signature and verification algorithm, of course, there is no "public key encryption, Private Key decryption"
Question: In the art of Java encryption and decryption (version 2), the author says: "The signature value of the RSA digital signature algorithm is the same as the key length ", however, in my tests, the results are inconsistent:
1) when I set the asymmetric key to 512, the length of the public key is 96 bits, and the length of the private key is 345 BITs, which is far from 512, so how is 512 calculated?
2) the message digest result length is 64 (the digest value's binary array length). Why is it the same as the key length?
If you have any questions, please give me some advice. Thank you!