Java安全之對稱加密、非對稱加密、數字簽名


Java中加密分為兩種方式一個是對稱加密,另一個是非對稱加密。對稱加密是因為加密和解密的鑰匙相同,而非對稱加密是加密和解密的鑰匙不同。

對稱加密與非對稱加密的區別:

對稱加密稱為密鑰加密,速度快,但加密和解密的鑰匙必須相同,只有通信雙方才能知道密鑰。

非對稱加密稱為公鑰加密,算法更加復雜,速度慢,加密和解密鑰匙不相同,任何人都可以知道公鑰,只有一個人持有私鑰可以解密。

對稱加密解密:

 

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM