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

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

Java中加密分爲兩種方式一個是對稱加密,另外一個是非對稱加密。對稱加密是由於加密和解密的鑰匙相同,而非對稱加密是加密和解密的鑰匙不一樣。算法

 

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

對稱加密稱爲密鑰加密,速度快,但加密和解密的鑰匙必須相同,只有通訊雙方纔能知道密鑰。網站

非對稱加密稱爲公鑰加密,算法更加複雜,速度慢,加密和解密鑰匙不相同,任何人均可以知道公鑰,只有一我的持有私鑰能夠解密。加密

 

對稱加密解密:spa

 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 //    }

 

基於口令的對稱加密與解密 .net

系統自動生成的Key不容易記憶,咱們可使用咱們容易記憶的口令同過java自帶的一個工具將它轉換成Key,在解密的時候咱們就能夠經過口令進行解密。code

 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     }

 

非對稱加密解密: 對象

非對稱加密是公鑰加密,私鑰來解密,這個我的作用的少一點,主要針對於大型的網站大型的企業blog

 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     } 
相關文章
相關標籤/搜索