前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JAVA中的加密算法之双向加密(二)

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

作者头像
幽鸿
发布2020-04-02 18:31:56
1.5K0
发布2020-04-02 18:31:56
举报

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

Java代码

    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()。 下面是一个简单的实例:

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()函数会为您的数据创建一个“指纹”并将它保存起来,供验证测试使用。下面就是如何使用它的一个简单例子:

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然后可以被用来再次加密用户输入的内容,并 将它与先前加密的字符串进行比对。下面一个例子说明了如何使用它:

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()库。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档