专栏首页大数据-数据人生JAVA中的加密算法之双向加密(二)

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

本节主要讲述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()库。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

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

           加密,是以某种特殊的算法改变原有的信息数据,使得未授权的用户即使获得了已加密的信息,但因不知解密的方法,仍然无法了解信息的内容。大体上分为双向加密...

    幽鸿
  • Sqoop-1.4.4工具import和export使用详解

    Sqoop可以在HDFS/Hive和关系型数据库之间进行数据的导入导出,其中主要使用了import和export这两个工具。这两个工具非常强大,提供了很多选项帮...

    幽鸿
  • Oracle笔记

    1.Oracle内容介绍:   (1)基本部分:oracle基本使用、用户管理、表管理   (2)高级部分:表的查询、权限和角色、函数、PL/SQL编程、数...

    幽鸿
  • Python爬虫进阶必备 | X中网密码加密算法分析

    aHR0cHM6Ly9wYXNzcG9ydC5rb25nemhvbmcuY29tL2xvZ2lu

    叫我龙总
  • PostgreSQL数据库透明数据加密概述

    最近一段时间,一直在和PostgreSQL社区合作开发TDE(Transparent data encryption,透明数据加密)。研究了一些密码学相关的知识...

    王果壳
  • SQL Server 数据加密功能解析

    通常来讲,数据加密分为对称加密和非对称加密。SQL Server 就使用了折中的方法,所以SQL Server 加密功能包含2个部分:数据加密和密钥管理。本文将...

    腾讯云数据库团队
  • 实战案例浅析JS加密 - 基础总结篇

    找了一圈发现越是大厂加密越是简单,安全防护之类的完全不靠js加密,扫码登陆才是关键。比如微信公众号平台的登陆加密就是简单的MD5,但人家有扫码登陆,此类情况比比...

    咸鱼学Python
  • 从技术应用层来分析常见的视频加密方式

    网络通信的工作有七层:物理层、数据链路层、网络层、传输层、会话层、表示层和应用层。在不同的层级上可以对数据进行加密,总的来说在根据加密技术应用的层级不同,加密的...

    点量小崔
  • 集中式云数据加密服务填补安全漏洞

    大多数云服务提供商提供数据加密服务,但是对一些用户来说,这种服务还不足以全面保护云端的企业数据。 针对静态数据和传输中数据采取的数据加密应该是云计算界的一种标准...

    静一
  • 加密通讯可以防止隐私窃取,为何我们都不用它?

    前言: 分享这篇文章的原因是这几天在上课的时候,密码学老师讲解的密码学把我吸引住了,说到什么加密解密,讲课逻辑性挺高的,我喜欢—>_<。 其实说到真正分享这篇文...

    FB客服

扫码关注云+社区

领取腾讯云代金券