JAVA中的加密算法之双向加密(二)

2020-04-02 18:31:56 浏览数 (1)

本节主要讲述Java双向加密算法中的非对称加密算法实现。 (二)、非对称加密 1976年,美国学者Dime和Henman为解决信息公开传送和密钥管理问题,提出一种新的密钥交换协议,允许在不安全的媒体上的通讯双方交换信息,安全地达成一致的密钥,这就是“公开密钥系统”。相对于“对称加密算法”这种方法也叫做“非对称加密算法”。 与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥 (privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。 1. RSA 公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。

Java代码

代码语言:javascript复制
    import java.security.InvalidKeyException;   
    import java.security.KeyPair;   
    import java.security.KeyPairGenerator;   
    import java.security.NoSuchAlgorithmException;   
    import java.security.interfaces.RSAPrivateKey;   
    import java.security.interfaces.RSAPublicKey;   
      
    import javax.crypto.BadPaddingException;   
    import javax.crypto.Cipher;   
    import javax.crypto.IllegalBlockSizeException;   
    import javax.crypto.NoSuchPaddingException;   
      
    public class EncrypRSA {   
           
        /**  
         * 加密  
         * @param publicKey  
         * @param srcBytes  
         * @return  
         * @throws NoSuchAlgorithmException  
         * @throws NoSuchPaddingException  
         * @throws InvalidKeyException  
         * @throws IllegalBlockSizeException  
         * @throws BadPaddingException  
         */  
        protected byte[] encrypt(RSAPublicKey publicKey,byte[] srcBytes)throws NoSuchAlgorithmException, 
         NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{   
            if(publicKey!=null){   
                //Cipher负责完成加密或解密工作,基于RSA   
                Cipher cipher = Cipher.getInstance("RSA");   
                //根据公钥,对Cipher对象进行初始化   
                cipher.init(Cipher.ENCRYPT_MODE, publicKey);   
                byte[] resultBytes = cipher.doFinal(srcBytes);   
                return resultBytes;   
            }   
            return null;   
        }   
           
        /**  
         * 解密   
         * @param privateKey  
         * @param srcBytes  
         * @return  
         * @throws NoSuchAlgorithmException  
         * @throws NoSuchPaddingException  
         * @throws InvalidKeyException  
         * @throws IllegalBlockSizeException  
         * @throws BadPaddingException  
         */  
        protected byte[] decrypt(RSAPrivateKey privateKey,byte[] srcBytes) throws NoSuchAlgorithmException, 
         NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{   
            if(privateKey!=null){   
                //Cipher负责完成加密或解密工作,基于RSA   
                Cipher cipher = Cipher.getInstance("RSA");   
                //根据公钥,对Cipher对象进行初始化   
                cipher.init(Cipher.DECRYPT_MODE, privateKey);   
                byte[] resultBytes = cipher.doFinal(srcBytes);   
                return resultBytes;   
            }   
            return null;   
        }   
      
        /**  
         * @param args  
         * @throws NoSuchAlgorithmException   
         * @throws BadPaddingException   
         * @throws IllegalBlockSizeException   
         * @throws NoSuchPaddingException   
         * @throws InvalidKeyException   
         */  
        public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, 
          NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {   
            EncrypRSA rsa = new EncrypRSA();   
            String msg = "郭XX-精品相声";   
            //KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象   
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");   
            //初始化密钥对生成器,密钥大小为1024位   
            keyPairGen.initialize(1024);   
            //生成一个密钥对,保存在keyPair中   
            KeyPair keyPair = keyPairGen.generateKeyPair();   
            //得到私钥   
            RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();                
            //得到公钥   
            RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();   
               
            //用公钥加密   
            byte[] srcBytes = msg.getBytes();   
            byte[] resultBytes = rsa.encrypt(publicKey, srcBytes);   
               
            //用私钥解密   
            byte[] decBytes = rsa.decrypt(privateKey, resultBytes);   
               
            System.out.println("明文是:"   msg);   
            System.out.println("加密后是:"   new String(resultBytes));   
            System.out.println("解密后是:"   new String(decBytes));   
        }   
      
    }  

import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
public class EncrypRSA {
     /** * 加密 * 
           @param publicKey * 
           @param srcBytes * 
           @return * 
           @throws NoSuchAlgorithmException * 
           @throws NoSuchPaddingException * 
           @throws InvalidKeyException * 
           @throws IllegalBlockSizeException * 
           @throws BadPaddingException */

        protected byte[] encrypt(RSAPublicKey publicKey,byte[] srcBytes) throws   
              NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
              IllegalBlockSizeException, BadPaddingException{
          if(publicKey!=null){
              //Cipher负责完成加密或解密工作,基于RSA
              Cipher cipher = Cipher.getInstance("RSA");
              //根据公钥,对Cipher对象进行初始化
              cipher.init(Cipher.ENCRYPT_MODE, publicKey);
              byte[] resultBytes = cipher.doFinal(srcBytes);
              return resultBytes;
          }return null;}

     /** * 解密  * 
          @param privateKey * 
          @param srcBytes * 
          @return * 
          @throws NoSuchAlgorithmException * 
          @throws NoSuchPaddingException * 
          @throws InvalidKeyException * 
          @throws IllegalBlockSizeException * 
          @throws BadPaddingException */
     protected byte[] decrypt( RSAPrivateKey privateKey,byte[] srcBytes) 
         throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,  
              IllegalBlockSizeException, BadPaddingException{
         if(privateKey!=null){
        //Cipher负责完成加密或解密工作,基于RSA
        Cipher cipher = Cipher.getInstance("RSA");
        //根据公钥,对Cipher对象进行初始化
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] resultBytes = cipher.doFinal(srcBytes);
        return resultBytes;}return null;}

    /** * 
         @param args * 
         @throws NoSuchAlgorithmException  * 
         @throws BadPaddingException  * 
         @throws IllegalBlockSizeException  * 
         @throws NoSuchPaddingException  * 
         @throws InvalidKeyException  */
    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, 
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
        EncrypRSA rsa = new EncrypRSA();
        String msg = "郭XX-精品相声";
        //KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
        KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
       //初始化密钥对生成器,密钥大小为1024位
        keyPairGen.initialize(1024);
       //生成一个密钥对,保存在keyPair中
        KeyPair keyPair = keyPairGen.generateKeyPair();
      //得到私钥RSA
       PrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
      //得到公钥RSA
      PublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
      //用公钥加密
      byte[] srcBytes = msg.getBytes();
      byte[] resultBytes = rsa.encrypt(publicKey, srcBytes);
     //用私钥解密
     byte[] decBytes = rsa.decrypt(privateKey, resultBytes);
     System.out.println("明文是:"   msg);
     System.out.println("加密后是:"   new String(resultBytes));
     System.out.println("解密后是:"   new String(decBytes));
 }}

2. DSA Digital Signature Algorithm (DSA)是Schnorr和ElGamal签名算法的变种,被美国NIST作为DSS(DigitalSignature Standard)。(感觉有点复杂,没有附代码) 详见http://63938525.iteye.com/blog/1051565 (三)、题外话 MySQL加密解密函数 MySQL有两个函数来支持这种类型的加密,分别叫做ENCODE()和DECODE()。 下面是一个简单的实例:

代码语言:javascript复制
Mysql代码

    mysql> INSERT INTO users (username,password) VALUES ('joe',ENCODE('guessme','abr'));   
      
    Query OK, 1 row affected (0.14 sec)  

mysql> INSERT INTO users (username,password) VALUES ('joe',ENCODE('guessme','abr'));Query OK, 1 row affected (0.14 sec)

其中,Joe的密码是guessme,它通过密钥abracadabra被加密。要注意的是,加密完的结果是一个二进制字符串,如下所示: 提示:虽然ENCODE()和DECODE()这两个函数能够满足大多数的要求,但是有的时候您希望使用强度更高的加密手段。在这种情况下,您可以使用AES_ENCRYPT()和AES_DECRYPT()函数,它们的工作方式是相同的,但是加密强度更高。 单向加密与双向加密不同,一旦数据被加密就没有办法颠倒这一过程。因此密码的验证包括对用户输入内容的重新加密,并将它与保存的密文进行比对,看是否匹配。一种简单的单向加密方式是MD5校验码。MySQL的MD5()函数会为您的数据创建一个“指纹”并将它保存起来,供验证测试使用。下面就是如何使用它的一个简单例子:

代码语言:javascript复制
Mysql代码

    mysql> INSERT INTO users (username,password) VALUES ('joe',MD5('guessme'));   
      
    Query OK, 1 row affected (0.00 sec)  

mysql> INSERT INTO users (username,password) VALUES ('joe',MD5('guessme'));Query OK, 1 row affected (0.00 sec)

或者,您考虑一下使用ENCRYPT()函数,它使用系统底层的crypt()系统调用来完成加密。这个函数有两个参数:一个是要被加密的 字符串,另一个是双(或者多)字符的“salt”。它然后会用salt加密字符串;这个salt然后可以被用来再次加密用户输入的内容,并 将它与先前加密的字符串进行比对。下面一个例子说明了如何使用它:

代码语言:javascript复制
Mysql代码

    mysql> INSERT INTO users (username,password) VALUES('joe', ENCRYPT('guessme','ab'));   
      
    Query OK, 1 row affected (0.00 sec)  

mysql> INSERT INTO users (username,password) VALUES('joe', ENCRYPT('guessme','ab'));Query OK, 1 row affected (0.00 sec)

提示:ENCRYPT()只能用在UNIX、LINIX系统上,因为它需要用到底层的crypt()库。

0 人点赞