• Java安全之对称加密、非对称加密、数字签名


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

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

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

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

    对称加密解密:

    [java] view plaincopy
     
    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,在解密的时候我们就可以通过口令进行解密。

    [java] view plaincopy
     
    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. }  


    非对称加密解密:

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

    [java] view plaincopy
     
    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进行签名

    [java] view plaincopy
     
      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. }   
  • 相关阅读:
    看了前辈缠中说禅及其反响,忍不住想说些东西
    利弗莫尔的操盘精华篇
    缠中说禅:教你炒股票108课(转载)
    评温斯坦的炒股书(非常重要,常看看)
    本散女2
    使用PHP-GTK编写一个windows桌面应用程序
    php.exe php-cgi.exe php-win.exe的区别
    php调试利器之phpdbg
    yaf框架安装配置
    phalcon框架安装
  • 原文地址:https://www.cnblogs.com/duanxz/p/3195098.html
Copyright © 2020-2023  润新知