zoukankan      html  css  js  c++  java
  • Java安全之对称加密、非对称加密、数字签名

    原文地址: http://blog.csdn.net/furongkang/article/details/6882039

    Java中加密分为两种方式一个是对称加密,另一个是非对称加密。对称加密是因为加密和解密的钥匙相同,而非对称加密是加密和解密的钥匙不同。

    对称加密与非对称加密的区别:

    对称加密称为密钥加密,速度快,但加密和解密的钥匙必须相同,只有通信双方才能知道密钥。

    非对称加密称为公钥加密,算法更加复杂,速度慢,加密和解密钥匙不相同,任何人都可以知道公钥,只有一个人持有私钥可以解密。

    对称加密解密:

     1     /*
     2      * 对称加密
     3      */
     4     private static void secretEncrypt() throws Exception {
     5         //使用Cipher的实例
     6         Cipher cipher =Cipher.getInstance("AES");
     7         
     8         //得到加密的钥匙
     9         SecretKey key =KeyGenerator.getInstance("AES").generateKey();
    10         
    11         //初始化加密操作,传递加密的钥匙
    12         cipher.init(Cipher.ENCRYPT_MODE,key);
    13         
    14         //将加密的钥匙写入secretKey.key文件中
    15         FileOutputStream fosKey=new FileOutputStream("secretKey.key");
    16         ObjectOutputStream oosSecretKey =new ObjectOutputStream(fosKey);
    17         oosSecretKey.writeObject(key);
    18         oosSecretKey.close();
    19         fosKey.close();
    20          
    21          //将加密的内容传递进去,返回加密后的二进制数据
    22         byte [] results =cipher.doFinal("哈哈哈哈哈".getBytes());
    23         
    24         //将加密后的二进制数据写入到secretContent.dat文件中
    25         FileOutputStream fosData=new FileOutputStream("secretContent.dat");
    26         fosData.write(results);
    27         fosData.close();
    28     }
    29     
    30     /*
    31      * 对称解密
    32      */
    33     private static void secretDecrypt() throws Exception{
    34         Cipher cipher =Cipher.getInstance("AES");
    35         
    36         //获取文件中的key进行解密
    37         FileInputStream fisKey=new FileInputStream("secretKey.key");
    38         ObjectInputStream oisKey =new ObjectInputStream(fisKey);
    39         Key key =(Key)oisKey.readObject();
    40         oisKey.close();
    41         fisKey.close();
    42         
    43         //初始化解密操作,传递加密的钥匙
    44         cipher.init(Cipher.DECRYPT_MODE,key);
    45         
    46         //获取文件中的二进制数据
    47         FileInputStream fisDat=new FileInputStream("secretContent.dat");
    48         //获取数据第一种方式
    49         byte [] src=new byte [fisDat.available()];
    50         int len =fisDat.read(src);
    51         int total =0;
    52         while(total<src.length){
    53             total +=len;
    54             len=fisDat.read(src,total,src.length-total);
    55         }
    56         //执行解密
    57         byte [] result=cipher.doFinal(src);
    58         fisDat.close();
    59         System.out.println(new String(result));
    60         
    61 //        读文件中的数据第二种方式
    62 //        ByteArrayOutputStream baos =new ByteArrayOutputStream();
    63 //        copyStream(fisDat, baos);
    64 //        byte [] result=cipher.doFinal(baos.toByteArray());
    65 //        fisDat.close();
    66 //        baos.close();
    67     }
    68     
    69 //    private static void copyStream(InputStream ips,OutputStream ops) throws Exception{
    70 //        byte [] buf =new byte[1024];
    71 //        int len=ips.read(buf);
    72 //        while(len!=-1){
    73 //            ops.write(buf,0,len);
    74 //            len  =ips.read(buf);
    75 //        }
    76 //    }

    基于口令的对称加密与解密 

    系统自动生成的Key不容易记忆,我们可以使用我们容易记忆的口令同过java自带的一个工具将它转换成Key,在解密的时候我们就可以通过口令进行解密。

     1     /*
     2      * 基于口令的对称加密
     3      */
     4     private static void secretEncrypt() throws Exception {
     5         //实例化工具
     6         Cipher cipher2=Cipher.getInstance("PBEWithMD5AndDES");
     7         
     8         //使用该工具将基于密码的形式生成Key
     9         SecretKey key2=SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(new PBEKeySpec("123".toCharArray()));
    10         PBEParameterSpec parameterspec=new PBEParameterSpec(new byte[]{1,2,3,4,5,6,7,8},1000);
    11         
    12         //初始化加密操作,同时传递加密的算法
    13         cipher2.init(Cipher.ENCRYPT_MODE,key2,parameterspec);
    14         
    15          //将要加密的数据传递进去,返回加密后的数据
    16         byte [] results =cipher2.doFinal("哈哈哈哈哈".getBytes());
    17         
    18         //将加密后的数据写入到文件中
    19         FileOutputStream fosData=new FileOutputStream("zxx.dat");
    20         fosData.write(results);
    21         fosData.close();
    22     }
    23     
    24     /*
    25      * 基于口令的对称解密
    26      */
    27     private static void secretDecrypt() throws Exception{
    28         Cipher cipher2=Cipher.getInstance("PBEWithMD5AndDES");
    29         SecretKey key2=SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(new PBEKeySpec("123".toCharArray()));
    30         PBEParameterSpec parameterspec=new PBEParameterSpec(new byte[]{1,2,3,4,5,6,7,8},1000);
    31         cipher2.init(Cipher.DECRYPT_MODE,key2,parameterspec);
    32         FileInputStream fisDat=new FileInputStream("zxx.dat");
    33         byte [] src=new byte [fisDat.available()];
    34         int len =fisDat.read(src);
    35         int total =0;
    36         while(total<src.length){
    37             total +=len;
    38             len=fisDat.read(src,total,src.length-total);
    39         }
    40         byte [] result=cipher2.doFinal(src);
    41         fisDat.close();
    42         System.out.println(new String(result));
    43     }

    非对称加密解密: 

    非对称加密是公钥加密,私钥来解密,这个个人做用的少一点,主要针对于大型的网站大型的企业

     1     /*
     2      * 公钥加密
     3      */
     4     private static void PublicEnrypt()throws Exception {
     5         Cipher cipher =Cipher.getInstance("RSA");
     6         //实例化Key
     7         KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");
     8         //获取一对钥匙
     9         KeyPair keyPair=keyPairGenerator.generateKeyPair();
    10         //获得公钥
    11         Key publicKey=keyPair.getPublic();
    12         //获得私钥 
    13         Key privateKey=keyPair.getPrivate();
    14         //用公钥加密
    15         cipher.init(Cipher.ENCRYPT_MODE, publicKey);
    16         byte [] result=cipher.doFinal("传智播客".getBytes("UTF-8"));
    17         //将Key写入到文件
    18         saveKey(privateKey,"zxx_private.key");
    19         //加密后的数据写入到文件
    20         saveData(result,"public_encryt.dat");
    21     }
    22     
    23     /*
    24      * 私钥解密
    25      */
    26     private static void privateDecrypt() throws Exception {
    27         Cipher cipher=Cipher.getInstance("RSA");
    28         //得到Key
    29         Key privateKey=readKey("zxx_private.key");
    30         //用私钥去解密
    31         cipher.init(Cipher.DECRYPT_MODE, privateKey);
    32         //读数据源
    33         byte [] src =readData("public_encryt.dat");
    34         //得到解密后的结果
    35         byte[] result=cipher.doFinal(src);
    36         //二进制数据要变成字符串需解码
    37         System.out.println(new String(result,"UTF-8"));
    38     }
    39 
    40     private static void saveData(byte[] result, String fileName) throws Exception {
    41         // TODO Auto-generated method stub
    42         FileOutputStream fosData=new FileOutputStream(fileName);
    43         fosData.write(result);
    44         fosData.close();
    45     }
    46     public static void saveKey(Key key,String fileName)throws Exception{
    47         FileOutputStream fosKey=new FileOutputStream(fileName);
    48         ObjectOutputStream oosSecretKey =new ObjectOutputStream(fosKey);
    49         oosSecretKey.writeObject(key);
    50         oosSecretKey.close();
    51         fosKey.close();
    52     }
    53     private static Key readKey(String fileName) throws Exception {
    54         FileInputStream fisKey=new FileInputStream(fileName);
    55         ObjectInputStream oisKey =new ObjectInputStream(fisKey);
    56         Key key=(Key)oisKey.readObject();
    57         oisKey.close();
    58         fisKey.close();
    59         return key;
    60     }
    61     private static byte[] readData(String filename) throws Exception {
    62         FileInputStream fisDat=new FileInputStream(filename);
    63         byte [] src=new byte [fisDat.available()];
    64         int len =fisDat.read(src);
    65         int total =0;
    66         while(total<src.length){
    67             total +=len;
    68             len=fisDat.read(src,total,src.length-total);
    69         }
    70         fisDat.close();
    71         return src;
    72     }

    数字签名: 

    数字签名的基础是公钥和私钥的非对称加密,发送者使用私钥加密的消息摘要(签名),接收者使用公钥解密消息摘要以验证签名是否是某个人。

    要证明这段数据是你发过来的,并且没有被别人改过,这就需要用到数字签名,首先我们对整个文档进行md5加密得到16个字节,然后把消息摘要和文档发过去,解密者首先对发过来的文档进行解密,解密后得到一个摘要(md5),对接收的文档进行md5加密,得到的md5结果匹配解密后的摘要,如果匹配成功的话证明没有修改过,我们使用Signature进行签名

     1     /* 
     2      * 使用私钥签名 
     3      */  
     4     private static void sign()throws Exception {  
     5         //实例化Key   
     6         KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");  
     7         //获取一对钥匙   
     8         KeyPair keyPair=keyPairGenerator.generateKeyPair();  
     9         //获得公钥   
    10         PublicKey publicKey=keyPair.getPublic();  
    11         //获得私钥    
    12         PrivateKey privateKey=keyPair.getPrivate();  
    13         
    14         //数字签名
    15         Signature signature =Signature.getInstance("SHA1withRSA");
    16         signature.initSign(privateKey);//用私钥签名
    17         signature.update("这里签名".getBytes());//对怎样的数据进行签名
    18         byte [] sign=signature.sign();  //获取签名的结果
    19         
    20         //保存公钥并写入文件中 
    21         saveKey(publicKey,"zxx_private.key");  
    22         //将签名后的数据写入到文件   
    23         saveData(sign,"public_encryt.dat");  
    24     }
    25       
    26     /* 
    27      * 公钥解密 
    28      */  
    29     private static void verify() throws Exception {  
    30         Signature signture =Signature.getInstance("SHA1withRSA");
    31         //获取到公钥
    32         PublicKey publicKey=(PublicKey)readKey("zxx_private.key");
    33         //初始化校验
    34         signture.initVerify(publicKey);
    35         //初始化签名对象
    36         signture.update("这里签名".getBytes());
    37         //读数据源   
    38         byte [] sign =readData("public_encryt.dat");  
    39         //返回匹配结果
    40         boolean isYouSigned=signture.verify(sign);
    41         //如果返回数据为true则数据没有发生修改,否则发生修改
    42         System.out.println(isYouSigned);
    43     } 
  • 相关阅读:
    Istio技术与实践02:源码解析之Istio on Kubernetes 统一服务发现
    Istio技术与实践01: 源码解析之Pilot多云平台服务发现机制
    深度剖析Kubernetes API Server三部曲
    深度剖析Kubernetes API Server三部曲
    深度剖析Kubernetes API Server三部曲
    深入了解Kubernetes REST API的工作方式
    Cassandra schema version 不一致
    ByteToMessageDecoder
    Byte Bit
    为什么要用Executors.defaultThreadFactory().newThread(run);创建线程?
  • 原文地址:https://www.cnblogs.com/AloneSword/p/3315624.html
Copyright © 2011-2022 走看看