摘要:序本文主要小結一下里頭的以及加解密。屬于塊加密,塊加密中有等幾種工作模式。與一樣在加密前需要對數據進行填充,不是很適合對流數據進行加密。
序
本文主要小結一下java里頭的AES以及RSA加解密。
AES
使用AES加密時需要幾個參數:
密鑰長度(Key Size)
AES算法下,key的長度有三種:128、192和256 bits。由于歷史原因,JDK默認只支持不大于128 bits的密鑰,而128 bits的key已能夠滿足商用安全需求。
加密模式(Cipher Mode)
分組密碼算法只能加密固定長度的分組,但是我們需要加密的明文長度可能會超過分組密碼的分組長度,這時就需要對分組密碼算法進行迭代,以便將一段很長的明文全部加密。而迭代的方法就稱為分組密碼的模式。
AES屬于塊加密(Block Cipher),塊加密中有CBC、ECB、CTR、OFB、CFB等幾種工作模式。
ECB過于簡單而不安全(ECB模式由于每塊數據的加密是獨立的因此加密和解密都可以并行計算,ECB模式最大的缺點是相同的明文塊會被加密成相同的密文塊,這種方法在某些環境下不能提供嚴格的數據保密性);
CFB可被施以重放攻擊;
OFB 和 CTR 都可被主動攻擊者反轉密文,而引起解密后明文中的相應比特也發生變化;CTR比之OFB,多出能支持并發計算的特性,此外CTR是流式密碼;
CBC雖不支持并行計算,但是卻是這些模式中最為安全的
本文使用CBC模式。
CBC模式對于每個待加密的密碼塊在加密前會先與前一個密碼塊的密文異或然后再用加密器加密。第一個明文塊與一個叫初始化向量的數據塊異或。CBC模式相比ECB有更高的保密性,但由于對每個數據塊的加密依賴與前一個數據塊的加密所以加密無法并行。與ECB一樣在加密前需要對數據進行填充,不是很適合對流數據進行加密。
填充方式(Padding)
由于塊加密只能對特定長度的數據塊進行加密,因此CBC、ECB模式需要在最后一數據塊加密前進行數據填充。
JDK則提供了PKCS5Padding。
初始向量(Initialization Vector)
生成AES KEY使用除ECB以外的其他加密模式均需要傳入一個初始向量,其大小與Block Size相等(AES的Block Size為128 bits)
public static String genKeyAES() throws Exception { KeyGenerator kenGen = KeyGenerator.getInstance(AES); kenGen.init(KEY_SIZE); SecretKey key = kenGen.generateKey(); String base64 = Base64.getEncoder().encodeToString(key.getEncoded()); return base64; }
加解密這里KEY_SIZE采用128
后面統一用base64將byte[]轉為字符串,方便展示、排查。
public static byte[] aesEncryptBytes(byte[] contentBytes, byte[] keyBytes) throws Exception { return cipherOperation(contentBytes, keyBytes, Cipher.ENCRYPT_MODE); } public static byte[] aesDecryptBytes(byte[] contentBytes, byte[] keyBytes) throws Exception { return cipherOperation(contentBytes, keyBytes, Cipher.DECRYPT_MODE); } private static byte[] cipherOperation(byte[] contentBytes, byte[] keyBytes, int mode) throws Exception { SecretKeySpec secretKey = new SecretKeySpec(keyBytes,AES); byte[] initParam = SIXTEEN_CHAR_INIT_VECTOR.getBytes(CHARSET); IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam); Cipher cipher = Cipher.getInstance(AES_CBC_PKCS5_PADDING); cipher.init(mode, secretKey, ivParameterSpec); return cipher.doFinal(contentBytes); }
RSA 生成密鑰對這里AES_CBC_PKCS5_PADDING為AES/CBC/PKCS5Padding,使用簡寫的AES默認就是這個值
public static KeyPair getKeyPair() throws Exception { KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA); keyPairGenerator.initialize(KEY_SIZE); KeyPair keyPair = keyPairGenerator.generateKeyPair(); return keyPair; } public static String getPublicKey(KeyPair keyPair){ PublicKey publicKey = keyPair.getPublic(); byte[] bytes = publicKey.getEncoded(); return Base64.getEncoder().encodeToString(bytes); } public static String getPrivateKey(KeyPair keyPair){ PrivateKey privateKey = keyPair.getPrivate(); byte[] bytes = privateKey.getEncoded(); return Base64.getEncoder().encodeToString(bytes); }
加解密這里KEY_SIZE用1024,RSA256,RSA512,RSA1024,RSA2048這四種,RSA后面的N代表位數(多少bit),位數越大,加密強度越大,需要破解需要的時間也就越長
目前主流密鑰長度至少都是1024bits以上,低于1024bit的密鑰已經不建議使用(安全問題)。那么上限在哪里?沒有上限,多大都可以使用。所以,主流的模值是1024位
public static byte[] publicEncrypt(byte[] content,PublicKey publicKey) throws Exception { Cipher cipher = Cipher.getInstance(RSA); cipher.init(Cipher.ENCRYPT_MODE,publicKey); byte[] bytes = cipher.doFinal(content); return bytes; } public static byte[] privateDecrypt(byte[] content,PrivateKey privateKey) throws Exception { Cipher cipher = Cipher.getInstance(RSA); cipher.init(Cipher.DECRYPT_MODE,privateKey); byte[] bytes = cipher.doFinal(content); return bytes; }
AES與RSA結合這里RSA即"RSA",默認是RSA/ECB/PKCS1Padding
RSA 比 AES 更難破解,因為它不需要擔心密鑰在傳遞過程中有泄露,只存在暴力破解一種可能;
AES的優勢是以分組為輪,加解密速度非???,一般而言,AES 速度上數百倍于 RSA
在實際應用中,我們會混合應用AES和RSA:
1生成一個一次性隨機密鑰,算法上采用 AES 的CBC模式 aes-128-cbc(加密分組為128比特)對文件進行加密
2加密完成后,為了安全的傳遞這個一次性隨機密鑰,我們使用接收方的RSA公鑰 對其進行加密,隨加密后的文件一起發送
3接收方使用RSA私鑰進行解密,得到AES密鑰原文,并用AES解密文件
這樣就充分利用了兩者的優勢.
public void testHyperCodec(){ KeyPair keyPair = RSAUtil.getKeyPair(); String pubKey = RSAUtil.getPublicKey(keyPair); String priKey = RSAUtil.getPrivateKey(keyPair); String password = "1234567890"; String aesRawKey = AESUtil.genKeyAES(); System.out.println("aes raw key:"+aesRawKey); String rsaEntryptAesKey = RSAUtil.publicEncryptString(aesRawKey,pubKey); System.out.println(rsaEntryptAesKey); String aesEntryptContent = AESUtil.aesEncryptStringByBase64Key(password,aesRawKey); System.out.println(aesEntryptContent); //decode String decodedAesKey = RSAUtil.privateDecryptString(rsaEntryptAesKey,priKey); String decodedPwd = AESUtil.aesDecryptStringByBase64Key(aesEntryptContent,decodedAesKey); System.out.println("aes key decoded:"+decodedAesKey); System.out.println(decodedPwd); }doc
AES加密 - iOS與Java的同步實現
對稱加密、公鑰加密和RSA
數據傳輸加密——非對稱加密算法RSA+對稱算法AES(適用于java,android和Web)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/70415.html
摘要:添加應用啟動類配置客戶端鏈接經過對稱加解密的配置微服務專門為測試經過對稱加解密的配置微服務微服務模塊。 SpringCloud(第 031 篇)配置客戶端ConfigClient鏈接經過對稱加解密的配置微服務 - 一、大致介紹 1、Git服務端的文件內容進行了加密處理,那么是不是配置客戶端拿到內容之后需要解密呢? 2、答案顯然不是的,因為這樣解密的話,先不說實現起來的難易程度,單從表面...
SpringCloud(第 033 篇)配置客戶端ConfigClient鏈接經過對稱加解密的配置微服務 - 一、大致介紹 1、在(第 031 篇)講解了如何鏈接對稱加密的配置服務端,而鏈接對稱非對稱加密的配置微服務也是同樣的; 2、配置客戶端不需要做什么加解密的配置,加解密的配置在服務端做就好了; 3、這里還順便列舉下配置路徑的規則: /****************************...
摘要:前情需要使用和實現同一個加解密算法,使版本加密的密文能夠由代碼解密,反之亦然。加密使用模式,需要一個向量,可增加加密算法的強度此處使用做轉碼。解密先用解密再將代碼加密出來的密鑰放到中進行解密大功告成,實現了在和的互轉。 前情 需要使用Python和Java實現同一個AES加解密算法,使Python版本加密的密文能夠由Java代碼解密,反之亦然。 Python實現 Python為3.6版...
摘要:前情需要使用和實現同一個加解密算法,使版本加密的密文能夠由代碼解密,反之亦然。加密使用模式,需要一個向量,可增加加密算法的強度此處使用做轉碼。解密先用解密再將代碼加密出來的密鑰放到中進行解密大功告成,實現了在和的互轉。 前情 需要使用Python和Java實現同一個AES加解密算法,使Python版本加密的密文能夠由Java代碼解密,反之亦然。 Python實現 Python為3.6版...
摘要:時間年月日星期一說明本文部分內容均來自慕課網。多用于網絡加密。散列函數函數或消息摘要函數主要作用散列函數用來驗證數據的完整性。 時間:2017年4月10日星期一說明:本文部分內容均來自慕課網。@慕課網:http://www.imooc.com教學示例源碼:https://github.com/zccodere/s...個人學習源碼:https://github.com/zccodere...
閱讀 2178·2023-04-25 19:06
閱讀 1375·2021-11-17 09:33
閱讀 1767·2019-08-30 15:53
閱讀 2582·2019-08-30 14:20
閱讀 3541·2019-08-29 12:58
閱讀 3534·2019-08-26 13:27
閱讀 501·2019-08-26 12:23
閱讀 485·2019-08-26 12:22