原文地址: 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 }