Java安全之對稱加密、非對稱加密、數字簽名
轉貼: http://www.cnblogs.com/duanxz/p/3195098.html
Java中加密分為兩種方式一個是對稱加密,另一個是非對稱加密。對稱加密是因為加密和解密的鑰匙相同,而非對稱加密是加密和解密的鑰匙不同。
對稱加密與非對稱加密的區別:
對稱加密稱為金鑰加密,速度快,但加密和解密的鑰匙必須相同,只有通訊雙方才能知道金鑰。
非對稱加密稱為公鑰加密,演算法更加複雜,速度慢,加密和解金鑰匙不相同,任何人都可以知道公鑰,只有一個人持有私鑰可以解密。
對稱加密解密:
/* * 對稱加密 */ private static void secretEncrypt() throws Exception { //使用Cipher的例項 Cipher cipher =Cipher.getInstance("AES"); //得到加密的鑰匙 SecretKey key =KeyGenerator.getInstance("AES").generateKey(); //初始化加密操作,傳遞加密的鑰匙 cipher.init(Cipher.ENCRYPT_MODE,key); //將加密的鑰匙寫入secretKey.key檔案中 FileOutputStream fosKey=new FileOutputStream("secretKey.key"); ObjectOutputStream oosSecretKey =new ObjectOutputStream(fosKey); oosSecretKey.writeObject(key); oosSecretKey.close(); fosKey.close(); //將加密的內容傳遞進去,返回加密後的二進位制資料 byte [] results =cipher.doFinal("哈哈哈哈哈".getBytes()); //將加密後的二進位制資料寫入到secretContent.dat檔案中 FileOutputStream fosData=new FileOutputStream("secretContent.dat"); fosData.write(results); fosData.close(); } /* * 對稱解密 */ private static void secretDecrypt() throws Exception{ Cipher cipher =Cipher.getInstance("AES"); //獲取檔案中的key進行解密 FileInputStream fisKey=new FileInputStream("secretKey.key"); ObjectInputStream oisKey =new ObjectInputStream(fisKey); Key key =(Key)oisKey.readObject(); oisKey.close(); fisKey.close(); //初始化解密操作,傳遞加密的鑰匙 cipher.init(Cipher.DECRYPT_MODE,key); //獲取檔案中的二進位制資料 FileInputStream fisDat=new FileInputStream("secretContent.dat"); //獲取資料第一種方式 byte [] src=new byte [fisDat.available()]; int len =fisDat.read(src); int total =0; while(total<src.length){ total +=len; len=fisDat.read(src,total,src.length-total); } //執行解密 byte [] result=cipher.doFinal(src); fisDat.close(); System.out.println(new String(result)); // 讀檔案中的資料第二種方式 // ByteArrayOutputStream baos =new ByteArrayOutputStream(); // copyStream(fisDat, baos); // byte [] result=cipher.doFinal(baos.toByteArray()); // fisDat.close(); // baos.close(); } // private static void copyStream(InputStream ips,OutputStream ops) throws Exception{ // byte [] buf =new byte[1024]; // int len=ips.read(buf); // while(len!=-1){ // ops.write(buf,0,len); // len =ips.read(buf); // } // }
基於口令的對稱加密與解密
系統自動生成的Key不容易記憶,我們可以使用我們容易記憶的口令同過java自帶的一個工具將它轉換成Key,在解密的時候我們就可以通過口令進行解密。
/* * 基於口令的對稱加密 */ private static void secretEncrypt() throws Exception { //例項化工具 Cipher cipher2=Cipher.getInstance("PBEWithMD5AndDES"); //使用該工具將基於密碼的形式生成Key SecretKey key2=SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(new PBEKeySpec("123".toCharArray())); PBEParameterSpec parameterspec=new PBEParameterSpec(new byte[]{1,2,3,4,5,6,7,8},1000); //初始化加密操作,同時傳遞加密的演算法 cipher2.init(Cipher.ENCRYPT_MODE,key2,parameterspec); //將要加密的資料傳遞進去,返回加密後的資料 byte [] results =cipher2.doFinal("哈哈哈哈哈".getBytes()); //將加密後的資料寫入到檔案中 FileOutputStream fosData=new FileOutputStream("zxx.dat"); fosData.write(results); fosData.close(); } /* * 基於口令的對稱解密 */ private static void secretDecrypt() throws Exception{ Cipher cipher2=Cipher.getInstance("PBEWithMD5AndDES"); SecretKey key2=SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(new PBEKeySpec("123".toCharArray())); PBEParameterSpec parameterspec=new PBEParameterSpec(new byte[]{1,2,3,4,5,6,7,8},1000); cipher2.init(Cipher.DECRYPT_MODE,key2,parameterspec); FileInputStream fisDat=new FileInputStream("zxx.dat"); byte [] src=new byte [fisDat.available()]; int len =fisDat.read(src); int total =0; while(total<src.length){ total +=len; len=fisDat.read(src,total,src.length-total); } byte [] result=cipher2.doFinal(src); fisDat.close(); System.out.println(new String(result)); }
非對稱加密解密:
非對稱加密是公鑰加密,私鑰來解密,這個個人做用的少一點,主要針對於大型的網站大型的企業
/* * 公鑰加密 */ private static void PublicEnrypt()throws Exception { Cipher cipher =Cipher.getInstance("RSA"); //例項化Key KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA"); //獲取一對鑰匙 KeyPair keyPair=keyPairGenerator.generateKeyPair(); //獲得公鑰 Key publicKey=keyPair.getPublic(); //獲得私鑰 Key privateKey=keyPair.getPrivate(); //用公鑰加密 cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte [] result=cipher.doFinal("傳智播客".getBytes("UTF-8")); //將Key寫入到檔案 saveKey(privateKey,"zxx_private.key"); //加密後的資料寫入到檔案 saveData(result,"public_encryt.dat"); } /* * 私鑰解密 */ private static void privateDecrypt() throws Exception { Cipher cipher=Cipher.getInstance("RSA"); //得到Key Key privateKey=readKey("zxx_private.key"); //用私鑰去解密 cipher.init(Cipher.DECRYPT_MODE, privateKey); //讀資料來源 byte [] src =readData("public_encryt.dat"); //得到解密後的結果 byte[] result=cipher.doFinal(src); //二進位制資料要變成字串需解碼 System.out.println(new String(result,"UTF-8")); } private static void saveData(byte[] result, String fileName) throws Exception { // TODO Auto-generated method stub FileOutputStream fosData=new FileOutputStream(fileName); fosData.write(result); fosData.close(); } public static void saveKey(Key key,String fileName)throws Exception{ FileOutputStream fosKey=new FileOutputStream(fileName); ObjectOutputStream oosSecretKey =new ObjectOutputStream(fosKey); oosSecretKey.writeObject(key); oosSecretKey.close(); fosKey.close(); } private static Key readKey(String fileName) throws Exception { FileInputStream fisKey=new FileInputStream(fileName); ObjectInputStream oisKey =new ObjectInputStream(fisKey); Key key=(Key)oisKey.readObject(); oisKey.close(); fisKey.close(); return key; } private static byte[] readData(String filename) throws Exception { FileInputStream fisDat=new FileInputStream(filename); byte [] src=new byte [fisDat.available()]; int len =fisDat.read(src); int total =0; while(total<src.length){ total +=len; len=fisDat.read(src,total,src.length-total); } fisDat.close(); return src; }
數字簽名:
數字簽名的基礎是公鑰和私鑰的非對稱加密,傳送者使用私鑰加密的訊息摘要(簽名),接收者使用公鑰解密訊息摘要以驗證簽名是否是某個人。
要證明這段資料是你發過來的,並且沒有被別人改過,這就需要用到數字簽名,首先我們對整個文件進行md5加密得到16個位元組,然後把訊息摘要和文件發過去,解密者首先對發過來的文件進行解密,解密後得到一個摘要(md5),對接收的文件進行md5加密,得到的md5結果匹配解密後的摘要,如果匹配成功的話證明沒有修改過,我們使用Signature進行簽名
/* * 使用私鑰簽名 */ private static void sign()throws Exception { //例項化Key KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA"); //獲取一對鑰匙 KeyPair keyPair=keyPairGenerator.generateKeyPair(); //獲得公鑰 PublicKey publicKey=keyPair.getPublic(); //獲得私鑰 PrivateKey privateKey=keyPair.getPrivate(); //數字簽名 Signature signature =Signature.getInstance("SHA1withRSA"); signature.initSign(privateKey);//用私鑰簽名 signature.update("這裡簽名".getBytes());//對怎樣的資料進行簽名 byte [] sign=signature.sign(); //獲取簽名的結果 //儲存公鑰並寫入檔案中 saveKey(publicKey,"zxx_private.key"); //將簽名後的資料寫入到檔案 saveData(sign,"public_encryt.dat"); } /* * 公鑰解密 */ private static void verify() throws Exception { Signature signture =Signature.getInstance("SHA1withRSA"); //獲取到公鑰 PublicKey publicKey=(PublicKey)readKey("zxx_private.key"); //初始化校驗 signture.initVerify(publicKey); //初始化簽名物件 signture.update("這裡簽名".getBytes()); //讀資料來源 byte [] sign =readData("public_encryt.dat"); //返回匹配結果 boolean isYouSigned=signture.verify(sign); //如果返回資料為true則資料沒有發生修改,否則發生修改 System.out.println(isYouSigned); }
相關文章
- 對稱加密、非對稱加密、RSA、訊息摘要、數字簽名、數字證書與HTTPS簡介加密HTTP
- 對稱加密與非對稱加密加密
- 非對稱加密中,加解密和簽名加密解密
- 資料加密(對稱加密和非對稱加密)加密
- Android 安全加密:非對稱加密Android加密
- Android安全加密:非對稱加密Android加密
- 對稱加密、非對稱加密、RSA(總結)加密
- 編碼與加密(對稱加密與非對稱加密)加密
- 非對稱加密和數字證書加密
- 對稱加密和非對稱加密(一)初步理解加密
- 加密原理詳解:對稱式加密VS非對稱式加密加密
- https中的對稱加密和非對稱加密HTTP加密
- 非對稱加密體系加密
- RSA 非對稱加密&解密加密解密
- 非對稱加密與OpenSSL加密
- ssh與非對稱加密加密
- 非對稱加密與 jwt加密JWT
- Android 安全加密:對稱加密Android加密
- Android安全加密:對稱加密Android加密
- 3分鐘告訴你什麼是 非對稱加密、對稱加密、公鑰、私鑰、數字證書、數字簽名、資訊摘要、中間人攻擊、CA、根證書加密
- 非對稱加密--RSA原理淺析加密
- Linux系統中對稱加密和非對稱加密區別是什麼?Linux加密
- Linux SSH是什麼?對稱加密和非對稱加密有何區別?Linux加密
- 聊聊對稱/非對稱加密在HTTPS中的應用加密HTTP
- 對稱、非對稱的加密技術是如何對網站資料進行雙重加密?加密網站
- Java加密技術(七)——非對稱加密演算法最高階ECCJava加密演算法
- golang 中,非對稱加密的實現Golang加密
- 非對稱加密技術:共享祕鑰加密
- 理解區塊鏈的非對稱加密區塊鏈加密
- 非對稱加密演算法的思考加密演算法
- 非對稱加密和證書總結加密
- 密碼學之對稱加密密碼學加密
- 對稱加密體系加密
- 應用加密1;非對稱加密演算法揭祕加密演算法
- 前後端資料加密傳輸 RSA非對稱加密後端加密
- golang 密碼學-2. 非對稱加密Golang密碼學加密
- RSA非對稱加密演算法淺析加密演算法
- 實現HTTPS系列第二彈之【非對稱加密,公鑰私鑰,數字簽名,OpenSSL及HTTPS等概念簡介】HTTP加密