Source author Wang Hui
Chapter 4 Basic Knowledge
1.1. Single-key password system
The single-key cryptography system is a traditional encryption algorithm, which means that the sender and receiver of the information use the same key for encryption and decryption.
Generally, the encryption algorithm is simple and efficient, the key is short, the encryption and decryption speed is fast, and deciphering is extremely difficult. However, encryption security relies on the security of key custody. It is a serious problem to securely transmit and keep keys on public computer networks, in addition, the key security is also a problem in the case of multiple users.
The single-key password system represents DES in the United States.
1.2. Message Summary
A message digest is a digital fingerprint of a data block. Calculate a data block of any length and generate a unique fingerprint (for SHA1, a 20-byte binary array ).
The message digest has two basic attributes:
It is difficult for two different packets to generate the same abstract.
It is difficult to generate a message for a specified digest, and the specified digest is calculated by the corresponding digest.
Representatives: SHA1 of the National Institute of Standards and Technology and MD5 proposed by Ronald Rivest of the Massachusetts Institute of Technology
1.3. Diffie-Hellman Key consistency Protocol
The key consistency protocol is an idea proposed by Diffie and Hellman, the founders of the public key cryptography system.
Prerequisites: two users are allowed to exchange information on the public media to generate a "consistent" and shared key.
Representative: Exponential Key Agreement Protocol)
1.4. asymmetric algorithms and public key systems
In 1976, Dittie and Hellman proposed a Key Exchange Protocol in their pioneering work "New Direction of cryptography" to solve the key management problem, it is allowed to exchange information between two parties on insecure media and transmit secret keys securely. On the basis of this new idea, an asymmetric key cryptography system (public key cryptography) emerged soon. In the public key system, encryption keys are different from decryption keys. They can be used by anyone who makes them public. The decryption keys are only known to the decrypted. They are called Public keys and Private keys respectively ).
Among all public key cryptography systems so far, RSA is the most famous and most widely used one. The RSA public key cryptography system was proposed by Professor R. Rivest, A. Shamir, and L. Adleman in 1977. The name of RSA is the first letter from the three inventors.
1.5. Digital Signature
The so-called digital signature means that the information sender uses its private key to perform RSA algorithm operations on the feature data (or digital fingerprint) extracted from the transmitted message, to ensure that the sender is not allowed to deny the information that has been sent (that is, non-repudiation), and to ensure that the information message is tampered with (that is, integrity) at the end of the signature ). After receiving the message, the message receiver can use the sender's public key to verify the digital signature.
Digital fingerprints that play an important role in digital signatures are generated by a special HASH function. The special requirements for these HASH functions are:
The received input message data has no length limit;
Generate a fixed-length Digest (digital fingerprint) Output for any input message data
The Digest can be easily calculated from the message;
It is difficult to generate a message for a specified digest, and the specified digest is calculated by the message;
It is difficult for two different packets to generate the same abstract.
Representative: DSA
Chapter 1 implementation in JAVA
2.1. Related
Diffie-Hellman Key consistency protocol and DES program require support from the JCE tool library, which can be downloaded and installed in the http://java.sun.com/security/index.html. For simple installation, copy all contents in jce1.2.1 \ lib to % java_home % \ lib \ ext. If the ext directory is not created, add jce1_2_1.jar and sunjce_provider.jar to CLASSPATH, for more details, see the corresponding user manual.
2.2. Use of message digest MD5 and SHA
Usage:
First, generate a MessageDigest class to determine the calculation method.
Java. security. MessageDigest alga = java. security. MessageDigest. getInstance ("SHA-1 ");
Add the information of the digest to be calculated
Alga. update (myinfo. getBytes ());
Calculate the abstract
Byte [] digesta = alga. digest ();
Your information and summary sent to others
Other people initialize with the same method, add information, and finally compare the summary.
Algb. isEqual (digesta, algb. digest ())
Related AIP
Java. security. MessageDigest class
Static getInstance (String algorithm)
Returns a MessageDigest object that implements the specified algorithm.
Parameter: algorithm name, such as SHA-1 or MD5
Void update (byte input)
Void update (byte [] input)
Void update (byte [] input, int offset, int len)
Add the information of the digest to be calculated
Byte [] digest ()
After the calculation is completed, return the computed Summary (for MD5, 16 bits, and SHA, 20 bits)
Void reset ()
Reset
Static boolean isEqual (byte [] digesta, byte [] digestb)
Whether the two abstracts are the same
Code:
Import java. security .*;
Public class myDigest {
Public static void main (String [] args ){
MyDigest my = new myDigest ();
My. testDigest ();
}
Public void testDigest ()
{
Try {
String myinfo = "my test information ";
// Java. security. MessageDigest alg = java. security. MessageDigest. getInstance ("MD5 ");
Java. security. MessageDigest alga = java. security. MessageDigest. getInstance ("SHA-1 ");
Alga. update (myinfo. getBytes ());
Byte [] digesta = alga. digest ();
System. out. println ("This information abstract is:" + byte2hex (digesta ));
// Send your information (myinfo) and digest (digesta) to other users in a certain way to determine whether the information is changed or transmitted normally
Java. security. MessageDigest algb = java. security. MessageDigest. getInstance ("SHA-1 ");
Algb. update (myinfo. getBytes ());
If (algb. isEqual (digesta, algb. digest ())){
System. out. println ("information check is normal ");
}
Else
{
System. out. println ("different abstract ");
}
}
Catch (java. security. NoSuchAlgorithmException ex ){
System. out. println ("invalid Digest algorithm ");
}
}
Public String byte2hex (byte [] B) // two-line conversion String
{
String hs = "";
String stmp = "";
For (int n = 0; n <B. length; n ++)
{
Stmp = (java. lang. Integer. toHexString (B [n] & 0XFF ));
If (stmp. length () = 1) hs = hs + "0" + stmp;
Else hs = hs + stmp;
If (n <B. length-1) hs = hs + ":";
}
Return hs. toUpperCase ();
}
}
2.3. Digital Signature DSA
A user must first generate his/her key pair and save them separately.
Generate a KeyPairGenerator instance
Java. security. KeyPairGenerator keygen = java. security. KeyPairGenerator. getInstance ("DSA ");
If the random generator is set, it will be initialized using the phase code.
SecureRandom secrand = new SecureRandom ();
Secrand. setSeed ("tttt". getBytes (); // initialize the random Generator
Keygen. initialize (512, secrand); // initialize the key generator
Otherwise
Keygen. initialize (512 );
Generate the Public Key pubkey and private key prikey
KeyPair keys = keygen. generateKeyPair (); // generate a key group
PublicKey pubkey = keys. getPublic ();
PrivateKey prikey = keys. getPrivate ();
Save them in myprikey. dat and mypubkey. dat, so that they will not be generated next time.
(It takes a long time to generate a key pair.
Java. io. ObjectOutputStream out = new java. io. ObjectOutputStream (new java. io. FileOutputStream ("myprikey. dat "));
Out. writeObject (prikey );
Out. close ();
Out = new java. io. ObjectOutputStream (new java. io. FileOutputStream ("mypubkey. dat "));
Out. writeObject (pubkey );
Out. close ();
Use his private key (prikey) to digitally sign the information he has confirmed (info) to generate a signature Array
Read a private key from a file)
Java. io. ObjectInputStream in = new java. io. ObjectInputStream (new java. io. FileInputStream ("myprikey. dat "));
PrivateKey myprikey = (PrivateKey) in. readObject ();
In. close ();
Initialize a Signature object and sign the information with the private key.
Java. security. Signature signet = java. security. Signature. getInstance ("DSA ");
Signet. initSign (myprikey );
Signet. update (myinfo. getBytes ());
Byte [] signed = signet. sign ();
Save the information and signature in a file (myinfo. dat)
Java. io. ObjectOutputStream out = new java. io. ObjectOutputStream (new java. io. FileOutputStream ("myinfo. dat "));
Out. writeObject (myinfo );
Out. writeObject (signed );
Out. close ();
Send the public key information and signature to other users.
Other users use his/her public key, signature, and info to verify whether the information is signed by him/her.
Read Public Key
Java. io. ObjectInputStream in = new java. io. ObjectInputStream (new java. io. FileInputStream ("mypubkey. dat "));
PublicKey pubkey = (PublicKey) in. readObject ();
In. close ();
Read signature and information
In = new java. io. ObjectInputStream (new java. io. FileInputStream ("myinfo. dat "));
String info = (String) in. readObject ();
Byte [] signed = (byte []) in. readObject ();
In. close ();
Initialize a Signature object and use the public key and Signature for verification.
Java. security. Signature signetcheck = java. security. Signature. getInstance ("DSA ");
Signetcheck. initVerify (pubkey );
Signetcheck. update (info. getBytes ());
If (signetcheck. verify (signed) {System. out. println ("normal signature ");}
This document uses Object streams to save and transmit keys. You can also use encoding to save keys.
Import java. security. spec .*
Import java. security .*
The rest is described as follows:
Public key is encoded using X.509. The example code is as follows: byte [] bobEncodedPubKey = mypublic. getEncoded (); // generate the encoding.
// Transfer binary encoding
// The following code is converted to the corresponding key object.
X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec (bobEncodedPubKey );
KeyFactory keyFactory = KeyFactory. getInstance ("DSA ");
PublicKey bobPubKey = keyFactory. generatePublic (bobPubKeySpec );
Private key is encoded with PKCS #8. The example code is as follows: byte [] bPKCS = myprikey. getEncoded ();
// Transfer binary encoding
// The following code is converted to the corresponding key object.
PKCS8EncodedKeySpec priPKCS8 = new PKCS8EncodedKeySpec (bPKCS );
KeyFactory keyf = KeyFactory. getInstance ("DSA ");
PrivateKey otherprikey = keyf. generatePrivate (priPKCS8 );
Common APIs
Java. security. KeyPairGenerator key generator class
Public static KeyPairGenerator getInstance (String algorithm) throws NoSuchAlgorithmException
Returns a KeyPairGenerator object using the specified algorithm.
Parameter: algorithm name, for example, "DSA", "RSA"
Public void initialize (int keysize)
Initializes the KeyPairGenerator object with the specified length. if the system is not initialized, the default value is 1024.
Parameter: the length of the keysize algorithm. The value range must be between 512 and 1024 and must be a multiple of 64.
Public void initialize (int keysize, SecureRandom random)
Initialize the KeyPairGenerator object with the specified length and random Generator
Parameter: the length of the keysize algorithm. The value range must be between 512 and 1024 and must be a multiple of 64.
Random uses the default random Device for the source of a random bit (for initialize (int keysize)
Public abstract KeyPair generateKeyPair ()
Generate new key pair
Java. security. KeyPair key pair class
Public PrivateKey getPrivate ()
Return Private Key
Public PublicKey getPublic ()
Return Public Key
Java. security. Signature Class
Public static Signature getInstance (String algorithm) throws NoSuchAlgorithmException
Returns the Signature object of a specified algorithm.
Algorithm: "DSA"
Public final void initSign (PrivateKey privateKey)
Throws InvalidKeyException
Initialize with the specified Private Key
Parameter: private key used for privateKey Signature
Public final void update (byte data)
Throws SignatureException
Public final void update (byte [] data)
Throws SignatureException
Public final void update (byte [] data, int off, int len)
Throws SignatureException
Add the information to be signed
Public final byte [] sign ()
Throws SignatureException
Returns an array of Signatures provided that initSign and update
Public final void initVerify (PublicKey publicKey)
Throws InvalidKeyException
Initialize with the specified public key
Parameter: public key used for publicKey Verification
Public final boolean verify (byte [] signature)
Throws SignatureException
Verify that the signature is valid only when initVerify is initialized.
Parameter: signature Array
*/
Import java. security .*;
Import java. security. spec .*;
Public class testdsa {
Public static void main (String [] args) throws java. security. NoSuchAlgorithmException, java. lang. Exception {
Testdsa my = new testdsa ();
My. run ();
}
Public void run ()
{
// Generate a key using a digital signature
// The first step is to generate a key pair. If the key pair has been generated, this process can be skipped. for users, myprikey. dat must be saved locally.
// While mypubkey. dat is released to other users
If (new java. io. File ("myprikey. dat"). exists () = false ){
If (generatekey () = false ){
System. out. println ("generate key pair failed ");
Return;
};
}
// Step 2: This User
// Read the private key from the file, sign a string, and save it in a file (myinfo. dat)
// And send myinfo. dat again
// For convenience, the digital signature is also put into the myifno. dat file. Of course, you can also send them separately
Try {
Java. io. ObjectInputStream in = new java. io. ObjectInputStream (new java. io. FileInputStream ("myprikey. dat "));
PrivateKey myprikey = (PrivateKey) in. readObject ();
In. close ();
// Java. security. spec. X509EncodedKeySpec pubX509 = new java. security. spec. X509EncodedKeySpec (bX509 );
// Java. security. spec. X509EncodedKeySpec pubkeyEncode = java. security. spec. X509EncodedKeySpec
String myinfo = "this is my information"; // The information to be signed
// Use the private key to generate a digital signature
Java. security. Signature signet = java. security. Signature. getInstance ("DSA ");
Signet. initSign (myprikey );
Signet. update (myinfo. getBytes ());
Byte [] signed = signet. sign (); // digital signature of information
System. out. println ("signed (Signature content) =" + byte2hex (signed ));
// Save the information and digital signature in a file
Java. io. ObjectOutputStream out = new java. io. ObjectOutputStream (new java. io. FileOutputStream ("myinfo. dat "));
Out. writeObject (myinfo );
Out. writeObject (signed );
Out. close ();
System. out. println ("signature and file generation succeeded ");
}
Catch (java. lang. Exception e ){
E. printStackTrace ();
System. out. println ("failed to sign and generate file ");
};
// Step 3
// Others obtain the public key and file of the user in public Mode
// Check the file with the public key of the user. If the file is successfully published by the user.
//
Try {
Java. io. ObjectInputStream in = new java. io. ObjectInputStream (new java. io. FileInputStream ("mypubkey. dat "));
PublicKey pubkey = (PublicKey) in. readObject ();
In. close ();
System. out. println (pubkey. getFormat ());
In = new java. io. ObjectInputStream (new java. io. FileInputStream ("myinfo. dat "));
String info = (String) in. readObject ();
Byte [] signed = (byte []) in. readObject ();
In. close ();
Java. security. Signature signetcheck = java. security. Signature. getInstance ("DSA ");
Signetcheck. initVerify (pubkey );
Signetcheck. update (info. getBytes ());
If (signetcheck. verify (signed )){
System. out. println ("info =" + info );
System. out. println ("normal signature ");
}
Else System. out. println ("non-signature normal ");
}
Catch (java. lang. Exception e) {e. printStackTrace ();};
}
// Generate a pair of files myprikey. dat and mypubkey. dat --- private key and public key,
// Send the Public Key (file, network, and other methods) to other users. The private key is stored locally.
Public boolean generatekey ()
{
Try {
Java. security. KeyPairGenerator keygen = java. security. KeyPairGenerator. getInstance ("DSA ");
// SecureRandom secrand = new SecureRandom ();
// Secrand. setSeed ("tttt". getBytes (); // initialize the random Generator
// Keygen. initialize (576, secrand); // initialize the key generator
Keygen. initialize (512 );
KeyPair keys = keygen. genKeyPair ();
// KeyPair keys = keygen. generateKeyPair (); // generate a key group
PublicKey pubkey = keys. getPublic ();
PrivateKey prikey = keys. getPrivate ();
Java. io. ObjectOutputStream out = new java. io. ObjectOutputStream (new java. io. FileOutputStream ("myprikey. dat "));
Out. writeObject (prikey );
Out. close ();
System. out. println ("Write object prikeys OK ");
Out = new java. io. ObjectOutputStream (new java. io. FileOutputStream ("mypubkey. dat "));
Out. writeObject (pubkey );
Out. close ();
System. out. println ("Write object pubkeys OK ");
System. out. println ("key pair generated successfully ");
Return true;
}
Catch (java. lang. Exception e ){
E. printStackTrace ();
System. out. println ("failed to generate the key pair ");
Return false;
};
}
Public String byte2hex (byte [] B)
{
String hs = "";
String stmp = "";
For (int n = 0; n <B. length; n ++)
{
Stmp = (java. lang. Integer. toHexString (B [n] & 0XFF ));
If (stmp. length () = 1) hs = hs + "0" + stmp;
Else hs = hs + stmp;
If (n <B. length-1) hs = hs + ":";
}
Return hs. toUpperCase ();
}
}
2.4. DESede/DES symmetric algorithm
Generate the key and save it. (For the code that is not saved here, refer to the method in DSA)
KeyGenerator keygen = KeyGenerator. getInstance (Algorithm );
SecretKey secret ey = keygen. generateKey ();
Encrypt the plaintext (myinfo) with the key to generate the ciphertext (cipherByte)
Cipher c1 = Cipher. getInstance (Algorithm );
C1.init (Cipher. ENCRYPT_MODE, Cipher ey );
Byte [] cipherByte = c1.doFinal (myinfo. getBytes ());
Transfer password and key. No code is available in this article. Refer to DSA.
.............
Decrypt ciphertext with a key
C1 = Cipher. getInstance (Algorithm );
C1.init (Cipher. DECRYPT_MODE, Cipher ey );
Byte [] clearByte = c1.doFinal (cipherByte );
Relatively speaking, the use of symmetric keys is very simple. for JCE, the supported technologies are DES, DESede, and Blowfish.
The object stream or binary code can be used for saving and transferring keys. The reference code is as follows:
SecretKey secret ey = keygen. generateKey ();
Byte [] desEncode = incluey. getEncoded ();
Javax. crypto. spec. SecretKeySpec destmp = new javax. crypto. spec. SecretKeySpec (desEncode, Algorithm );
SecretKey mysecretey = destmp;
Related APIs
KeyGenerator has been described in DSA. After JCE is added, the following parameters can be entered in the instance:
DES, DESede, Blowfish, HmacMD5, HmacSHA1
Javax. crypto. Cipher encryptor
Public static final Cipher getInstance (java. lang. String transformation)
Throws java. security. NoSuchAlgorithmException,
NoSuchPaddingException
Returns the Cipher object of a specified method.
Parameter: transformation Method Name (DES, DESede, Blowfish are available)
Public final void init (int opmode, java. security. Key key)
Throws java. security. InvalidKeyException
Initializes a Cipher object with the specified key and mode.
Parameter: opmode (ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE, UNWRAP_MODE)
Key
Public final byte [] doFinal (byte [] input)
Throws java. lang. IllegalStateException,
IllegalBlockSizeException,
BadPaddingException
Encode the strings in the input, and return the binary strings after processing. Whether to return the decrypted text or the decrypted text is determined by the opmode in init.
NOTE: If update exists before the execution of this method, it will process all updat and the input. Otherwise, it will be the content of this inout.
/*
Security Program DESede/DES Test
*/
Import java. security .*;
Import javax. crypto .*;
Public class testdes {
Public static void main (String [] args ){
Testdes my = new testdes ();
My. run ();
}
Public void run (){
// Add a new security algorithm. If JCE is used, add it.
Security. addProvider (new com. sun. crypto. provider. SunJCE ());
String Algorithm = "DES"; // defines the encryption Algorithm. DES, DESede, and Blowfish can be used.
String myinfo = "information to be encrypted ";
Try {
// Generate the key
KeyGenerator keygen = KeyGenerator. getInstance (Algorithm );
SecretKey secret ey = keygen. generateKey ();
// Encryption
System. out. println ("binary string before encryption:" + byte2hex (myinfo. getBytes ()));
System. out. println ("pre-encryption information:" + myinfo );
Cipher c1 = Cipher. getInstance (Algorithm );
C1.init (Cipher. ENCRYPT_MODE, Cipher ey );
Byte [] cipherByte = c1.doFinal (myinfo. getBytes ());
System. out. println ("encrypted binary string:" + byte2hex (cipherByte ));
// Decrypt
C1 = Cipher. getInstance (Algorithm );
C1.init (Cipher. DECRYPT_MODE, Cipher ey );
Byte [] clearByte = c1.doFinal (cipherByte );
System. out. println ("decrypted binary string:" + byte2hex (clearByte ));
System. out. println ("decrypted information:" + (new String (clearByte )));
}
Catch (java. security. NoSuchAlgorithmException e1) {e1.printStackTrace ();}
Catch (javax. crypto. NoSuchPaddingException e2) {e2.printStackTrace ();}
Catch (java. lang. Exception e3) {e3.printStackTrace ();}
}
Public String byte2hex (byte [] B) // two-line conversion String
{
String hs = "";
String stmp = "";
For (int n = 0; n <B. length; n ++)
{
Stmp = (java. lang. Integer. toHexString (B [n] & 0XFF ));
If (stmp. length () = 1) hs = hs + "0" + stmp;
Else hs = hs + stmp;
If (n <B. length-1) hs = hs + ":";
}
Return hs. toUpperCase ();
}
}
2.5. Diffie-Hellman Key consistency Protocol
The Exponential Key Agreement Protocol proposed by Diffie and Hellman, the founder of the public Key cryptography system, is not required
Address: http://www.zaoxue.com/article/tech-54324.htm