当前位置: 首页 > 后端技术 > Java

一文搞懂对称加密:加密算法、工作模式、填充方式、代码实现

时间:2023-04-01 22:25:08 Java

涓€绡囨枃绔犵悊瑙e绉板姞瀵嗭細鍔犲瘑绠楁硶銆佸伐浣滄ā寮忋€佸~鍏呮柟寮忋€佷唬鐮佸疄鐜?blog-demos涓婁竴绡囦粙缁嶄簡銆婂崟鍚戞暎鍒楀姞瀵嗐€嬶紝鏄竴绉嶆秷鎭憳瑕佺畻娉曘€傝绠楁硶鍦ㄤ俊鎭畨鍏ㄩ鍩熸湁寰堝閲嶈鐨勫簲鐢ㄥ満鏅紝濡傦細鐢ㄦ埛瀵嗙爜淇濇姢銆佹暟瀛楃鍚嶃€佹枃浠跺畬鏁存€ф牎楠屻€佷簯鐩樹紶杈撶瓑銆傚崟鍚戝搱甯屽姞瀵嗗彧鑳藉姞瀵嗘秷鎭紙涓ユ牸鏉ヨ鏄负浜嗚绠楁秷鎭殑鎽樿锛夈€傝瑙e瘑瀵嗘枃锛岄渶瑕佷娇鐢ㄥ叾浠栧姞瀵嗘柟娉曘€備粖澶╂垜浠氨鏉ヤ粙缁嶄竴绉嶅湪淇℃伅瀹夊叏棰嗗煙姣旇緝閲嶈鐨勫姞瀵嗘柟寮忊€斺€斿绉板姞瀵嗐€備互涓嬩负鏈枃鍐呭锛氬姞瀵嗐€佽В瀵嗐€佸瘑閽ュ姞瀵嗭紙Encrypt锛夋槸浠庢槑鏂囩敓鎴愬瘑鏂囩殑姝ラ锛岃В瀵嗭紙Decrypt锛夋槸浠庡瘑鏂囨仮澶嶆槑鏂囩殑姝ラ锛岃繖涓や釜姝ラ閮介渶瑕佷娇鐢ㄧ殑瀵嗘枃銆傞敭锛堥敭锛夈€傝繖涓庢垜浠幇瀹炰腑鐢ㄩ挜鍖欓攣瀹氬拰瑙i攣鏄竴鏍风殑銆備粈涔堟槸瀵圭О瀵嗙爜鏈绉板瘑鐮佹湳锛圫ymmetricCryptography锛夋槸瀵嗙爜瀛︿腑鐨勪竴绉嶅姞瀵嗙畻娉曪紝瀹冧娇鐢ㄧ浉鍚岀殑瀵嗛挜杩涜鍔犲瘑鍜岃В瀵嗐€傚绉板姞瀵嗕篃绉颁负鍏变韩瀵嗛挜鍔犲瘑銆傚畠鏈€澶х殑缂虹偣鏄绉板姞瀵嗙殑瀹夊叏鎬т緷璧栦簬瀵嗛挜銆備竴鏃︽硠闇诧紝灏辨剰鍛崇潃浠讳綍浜洪兘鍙互瑙e瘑娑堟伅銆傚绉板姞瀵嗙殑浼樼偣鏄姞瀵嗛€熷害蹇紝鎵€浠ヨ鐢ㄥ湪寰堝鍦哄悎銆傚父鐢ㄧ畻娉曟湰鑺備粙缁嶅绉板姞瀵嗙殑涓€浜涘父鐢ㄧ畻娉曪紝鍖呮嫭DES銆?DES銆丄ES銆侱ES绠楁硶DES锛圖ataEncryptionStandard锛屼腑鏂囷細鏁版嵁鍔犲瘑鏍囧噯锛夋槸涓€绉嶅绉板姞瀵嗙畻娉曘€傝绠楁硶浜?976骞磋缇庡浗鑱旈偊鏀垮簻鍥藉鏍囧噯灞€纭畾涓鸿仈閭︽暟鎹鐞嗘爣鍑嗭紙FIPS锛夛紝骞朵簬1977骞村彂甯冿紝闅忓悗鍦ㄥ浗闄呬笂骞夸负娴佷紶銆備絾鏄殢鐫€璁$畻鏈虹殑杩涙锛孌ES宸茬粡鍙互琚毚鍔涚牬瑙o紝鎵€浠ヨ绠楁硶宸茬粡涓嶅畨鍏ㄤ簡銆侱ES鏄竴绉嶅垎缁勫瘑鐮侊紙BlockCipher锛屾垨鍧楀姞瀵嗭級锛屽畠浠?4浣嶄负涓€缁勫鏄庢枃杩涜鍔犲瘑锛屾瘡缁勭敓鎴?4浣嶅瘑鏂囥€傚畠鐨勫瘑閽ラ暱搴︽槸56浣嶏紙鎸夌収瑙勮寖锛屽瘑閽ラ暱搴︽槸64浣嶏紝浣嗙敱浜庢瘡7浣嶈缃竴涓敤浜庨敊璇鏌ョ殑浣嶏紝鎵€浠ュ疄闄呴暱搴︽槸56浣嶏級銆?DES绠楁硶涓夐噸鏁版嵁鍔犲瘑绠楁硶锛圱ripleDataEncryptionAlgorithm锛岀畝绉癟DEA锛夛紝绠€绉?DES锛圱riple-DES锛夛紝鏄疍ES鐨勫寮虹増锛岀浉褰撲簬瀵规瘡缁勬暟鎹簲鐢ㄤ笁娆ES绠楁硶銆傜敱浜嶥ES绠楁硶鐨勫瘑閽ラ暱搴﹀お鐭紝寰堝鏄撹鏆村姏鐮磋В銆備负浜嗚В鍐宠繖涓棶棰橈紝璁捐浜嗚繖涓畻娉曘€傚畠浣跨敤涓€绉嶇畝鍗曠殑鏂规硶閫氳繃澧炲姞DES瀵嗛挜鐨勯暱搴︽潵閬垮厤绫讳技鐨勬敾鍑伙紝鑰屼笉鏄竴绉嶅叏鏂扮殑瀵嗙爜绠楁硶銆傛瘡娆″簲鐢―ES鏃讹紝璇ョ畻娉曢兘浣跨敤涓嶅悓鐨勫瘑閽ワ紝鍥犳瀛樺湪涓変釜鐙珛鐨勫瘑閽ャ€傝繖涓変釜瀵嗛挜缁勫悎鍦ㄤ竴璧凤紝灏辨槸涓€涓暱搴︿负168锛?6+56+56锛変綅鐨勫瘑閽ワ紝鎵€浠?DES绠楁硶鐨勫瘑閽ユ€婚暱搴︿负168浣嶃€?DES鐨勫姞瀵嗚繃绋嬩笉鏄疍ES鍔犲瘑鐨勪笁娆★紙鍔犲瘑鈫掑姞瀵嗏啋鍔犲瘑锛夛紝鑰屾槸鎸夌収瀵嗛挜1銆佸瘑閽?銆佸瘑閽?鐨勯『搴忚繘琛屽姞瀵嗏啋瑙e瘑鈫掑姞瀵嗙殑杩囩▼銆?DES鐨勮В瀵嗚繃绋嬪氨鏄笌鍔犲瘑鐩稿弽锛岃В瀵嗏啋鍔犲瘑鈫掕В瀵嗙殑鎿嶄綔鎸夌収瀵嗛挜3銆佸瘑閽?銆佸瘑閽?鐨勯『搴忚繘琛屻€侫ES绠楁硶AES锛圓dvancedEncryptionStandard锛夛紝鍗抽珮绾у姞瀵嗘爣鍑嗭紝鏄竴绉嶆柊鐨勫绉板姞瀵嗘浛浠ES绠楁硶鐨勭畻娉曘€侫ES绠楁硶閫夎嚜涓栫晫鍚勫湴鐨勫叕鍙稿拰瀵嗙爜瀛﹀鎻愪氦鐨勫绉板瘑鐮佺畻娉曘€傛渶缁圧ijndael鍔犲瘑绠楁硶鑾疯儨锛屾墍浠ES涔熻绉颁负Rijndael鍔犲瘑绠楁硶銆侫ES涔熸槸涓€绉嶅垎缁勫瘑鐮侊紝鍏跺垎缁勯暱搴︿负128浣嶏紝瀵嗛挜闀垮害鍙互鏄?28浣嶃€?92浣嶆垨256浣嶃€傚垎缁勫瘑鐮佹柟寮忎笂闈粙缁嶇殑DES銆?DES銆丄ES閮芥槸鍒嗙粍瀵嗙爜锛屽彧鑳藉姞瀵嗗浐瀹氶暱搴︾殑鏄庢枃銆傚鏋滈渶瑕佸姞瀵嗘洿闀跨殑鏄庢枃锛屽氨闇€瑕佸鍒嗙粍瀵嗙爜杩涜杩唬锛屽垎缁勫瘑鐮佺殑杩唬鏂规硶绉颁负鍒嗙粍瀵嗙爜鐨勬ā寮忥紙Model锛夈€傛€讳箣锛氬垎缁勫瘑鐮佺殑妯″紡灏辨槸鍒嗙粍瀵嗙爜鐨勮凯浠f硶銆傚垎缁勫瘑鐮佹湁澶氱妯″紡锛岃繖閲屼富瑕佷粙缁嶄互涓嬪嚑绉嶏細ECB銆丆BC銆丆FB銆丱FB銆丆TR銆傛槑鏂囧垎缁勫拰瀵嗘枃鍒嗙粍鍦ㄤ笅闈㈢殑妯″紡浠嬬粛涓紝浼氱敤鍒颁袱涓湳璇€傝繖閲屽厛浠嬬粛涓€涓嬶細鍦ㄥ垎缁勫瘑鐮佷腑锛屾垜浠О姣忎竴缁勭殑鏄庢枃涓烘槑鏂囧垎缁勶紝姣忎竴缁勭敓鎴愮殑瀵嗘枃绉颁负瀵嗘枃銆傛枃鏈垎缁勩€傚鏋滃皢鎵€鏈夋槑鏂囩粍缁勫悎璧锋潵褰㈡垚瀹屾暣鐨勬槑鏂囷紙鍏堝拷鐣ュ~鍏咃級锛屽垯灏嗘墍鏈夊瘑鏂囩粍缁勫悎璧锋潵褰㈡垚瀹屾暣鐨勫瘑鏂囥€侲CB妯″紡ECB锛圗lectronicCodeBook锛夋ā寮忥紝鍗崇數瀛愬瘑鐮佹湰妯″紡銆傝繖绉嶆ā寮忔槸鎶婃槑鏂囧垎缁勶紝鍔犲瘑鍚庣洿鎺ュ彉鎴愬瘑鏂囩粍锛岀粍涔嬮棿娌℃湁鍏崇郴銆侲CB妯″紡鏄墍鏈夋ā寮忎腑鏈€绠€鍗曠殑涓€绉嶃€傝繖绉嶆ā寮忎笅鏄庢枃缁勫拰瀵嗘枃缁勬槸涓€涓€瀵瑰簲鐨勩€傚鏋滄槑鏂囩粍鐩稿悓锛屽垯瀵嗘枃缁勪篃蹇呴』鐩稿悓銆傚洜姝わ紝ECB妯″紡涔熸槸鏈€涓嶅畨鍏ㄧ殑妯″紡銆侰BC妯″紡CBC锛圕ipherBlockChaining锛夋ā寮忥紝鍗冲瘑鐮佸潡閾炬帴妯″紡銆傝妯″紡鍏堝皢鏄庢枃鍧椾笌鍓嶄竴涓瘑鏂囧潡杩涜寮傛垨杩愮畻锛屽啀杩涜鍔犲瘑銆傚彧鏈夌涓€涓槑鏂囧寘姣旇緝鐗规畩锛岄渶瑕佹彁鍓嶇敓鎴愪竴涓笌璇ュ寘闀垮害鐩稿悓鐨勬瘮鐗瑰簭鍒楄繘琛屽紓鎴栬繍绠椼€傝繖涓綅搴忓垪绉颁负鍒濆鍖栧悜閲忥紙InitializationVector锛夛紝绠€绉癐V銆侰FB妯″紡CFB锛圕ipherFeedBack锛夋ā寮忥紝鍗冲瘑鏂囧弽棣堟ā寮忋€傝妯″紡鍏堝鍓嶄竴涓瘑鏂囩粍杩涜鍔犲瘑锛屽啀涓庡綋鍓嶆槑鏂囩粍杩涜寮傛垨杩愮畻锛岀敓鎴愬瘑鏂囩粍銆傚悓鏍风殑CFB妯″紡涔熼渶瑕両V銆侽FB妯″紡OFB锛圤utputFeedBack锛夋ā寮忥紝鍗宠緭鍑哄弽棣堟ā寮忋€傝妯″紡浼氱敓鎴愪竴涓瘑閽ユ祦锛屽嵆瀵嗙爜绠楁硶鐨勫墠涓€涓緭鍑哄€煎皢浣滀负褰撳墠瀵嗙爜绠楁硶鐨勮緭鍏ュ€笺€傜劧鍚庡皢杈撳叆鍊间笌鏄庢枃缁勮繘琛屽紓鎴栬繍绠楋紝璁$畻鍑哄瘑鏂囩粍銆傛妯″紡闇€瑕佷竴涓狪V锛屽畠琚姞瀵嗕负绗竴涓暟鎹寘鐨勮緭鍏ャ€侰TR妯″紡CTR(Counter)妯″紡锛屽嵆璁℃暟鍣ㄦā寮忋€傝妯″紡杩樹細鐢熸垚涓€涓瘑閽ユ祦锛屽畠浼氶€掑涓€涓鏁板櫒浠ョ敓鎴愪竴涓繛缁殑瀵嗛挜娴併€傝鏁板櫒鍔犲瘑鍚庯紝鍐嶄笌鏄庢枃缁勮繘琛屽紓鎴栬繍绠楋紝璁$畻鍑哄瘑鏂囩粍銆傚垎缁勫瘑鐮佺殑濉厖鍦ㄥ垎缁勫瘑鐮佷腑锛屽綋鏁版嵁闀垮害涓嶆弧瓒冲垎缁勯暱搴︽椂锛岄渶瑕佸灏鹃儴鏄庢枃鍒嗙粍杩涜涓€瀹氱殑濉厖銆傝繖绉嶅~鍏呭熬鍧楁暟鎹殑鏂规硶绉颁负濉厖銆侼oPadding琛ㄧず涓嶈繘琛屽~鍏咃紝鏄庢枃闀垮害蹇呴』鏄姞瀵嗙畻娉曞潡闀垮害鐨勬暣鏁板€嶃€?..|DDDDDDDDDDDDDD|DDDDDDDDDDDDDD|ANSIX9.23鍦ㄥ~鍏呭瓧鑺傚簭鍒椾腑锛屾渶鍚庝竴涓瓧鑺傚~鍏呭埌瑕佸~鍏呯殑瀛楄妭闀垮害锛屽叾浣欏瓧鑺傚~鍏?銆?..|DDDDDDDDDDDDDD|DDDDDD00000004|ISO10126鍦ㄥ~鍏呭瓧鑺傚簭鍒椾腑锛屾渶鍚庝竴涓瓧鑺傜敤寰呭~鍏呭瓧鑺傜殑闀垮害濉厖锛屽叾浣欏瓧鑺傜敤闅忔満鏁板~鍏呫€?..|DDDDDDDDDDDDDD|DDDDDD81A62304|鍦≒KCS#5鍜孭KCS#7涓紝姣忎釜瀛楄妭濉厖鐨勬槸瑕佸~鍏呯殑瀛楄妭鐨勯暱搴︺€?..|DDDDDDDDDDDDDD|DDDDDD04040404|ISO/IEC7816-4鍦ㄥ~鍏呭瓧鑺傚簭鍒椾腑锛岀涓€涓瓧鑺傚~鍏呭浐瀹氬€?0锛屽叾浣欏瓧鑺傚~鍏?銆傚鏋滃彧濉竴涓瓧鑺傦紝鐩存帴濉?0銆?..|DDDDDDDDDDDDDD|DDDDDD80000000|...|DDDDDDDDDDDDDD|DDDDDDDDDDDD80|ZeroPaddinginpaddingbytes搴忓垪涓紝姣忎釜瀛楄妭鐢?濉厖銆?..|DDDDDDDDDDDDDD|DDDDDDDD00000000|Java浠g爜瀹炵幇Java宸茬粡鍦ㄥ簳灞傚皝瑁呬簡瀵圭О鍔犲瘑鐨勫疄鐜帮紝鎴戜滑鍙渶瑕佷娇鐢ㄥ嵆鍙€傜幇鍦ㄤ粙缁嶅嚑涓噸瑕佺殑绫伙細SecureRandom绫籗ecureRandom绫绘槸涓€涓己鑰屽畨鍏ㄧ殑闅忔満鏁扮敓鎴愬櫒锛圧andomNumberGenerator锛岀畝绉帮細RNG锛夛紝鎺ㄨ崘鐢ㄤ簬鍔犲瘑鐩稿叧鐨勯殢鏈烘暟鐢熸垚鍣ㄣ€傛垜浠彲浠ラ€氳繃鏋勯€犳柟娉曠敓鎴愪竴涓疄渚嬶紝鎴栬€呬紶閫掍竴涓猻eed缁欐瀯閫犳柟娉曟潵鍒涘缓涓€涓疄渚嬨€係ecureRandom闅忔満=newSecureRandom();KeyGenerator绫籏eyGenerator绫绘槸瀵圭О瀵嗙爜鐨勫瘑閽ョ敓鎴愬櫒锛岄渶瑕佹寚瀹氫竴绉嶅姞瀵嗙畻娉曟潵鐢熸垚鐩稿簲鐨勫瘑閽ャ€侸ava鏀寔鐨勭畻娉曪細AES(128)DES(56)DESede(168)HmacSHA1HmacSHA256涓嬮潰鏄竴浜涙爣鍑嗙畻娉曠殑浠嬬粛锛氱敓鎴愬瘑閽ョ殑浠g爜濡備笅锛?***閫氳繃瀵嗙爜鑾峰彇Key瀵硅薄锛宎lgorithm**@paramkeysecretKey*@paramalgorithm绠楁硶锛屼緥濡傦細AES(128),DES(56),DESede(168),HmacSHA1,HmacSHA256*@returnkeyKey*@throwsException*/privatestaticKeygetKey(byte[]key,Stringalgorithm)throwsException{//閫氳繃绠楁硶鑾峰彇KeyGenerator瀵硅薄KeyGeneratorkeyGenerator=KeyGenerator.getInstance(algorithm);//浣跨敤瀵嗛挜浣滀负闅忔満鏁版潵鍒濆鍖朘eyGenerator瀵硅薄keyGenerator.init(newSecureRandom(key));//鐢熸垚KeyreturnkeyGenerator.generateKey();}Cipher绫籆ipher绫绘彁渚涘姞瀵嗗拰瑙e瘑鍔熻兘銆傝绫婚渶瑕佹寚瀹氫竴涓浆鎹紙Transformation锛夋潵鍒涘缓瀹炰緥锛岃浆鎹㈢殑鍛藉悕鏂瑰紡锛氱畻娉曞悕绉?宸ヤ綔妯″紡/濉厖鏂瑰紡銆侸ava鏀寔浠ヤ笅杞崲锛欰ES/CBC/NoPadding(128)AES/CBC/PKCS5Padding(128)AES/ECB/NoPadding(128)AES/ECB/PKCS5Padding(128)DES/CBC/NoPadding(56)DES/CBC/PKCS5Padding(56)DES/ECB/NoPadding(56)DES/ECB/PKCS5Padding(56)DESede/CBC/NoPadding(168)DESede/CBC/PKCS5Padding(168)DESede/ECB/NoPadding(168)DESede/ECB/PKCS5Padding(168)RSA/ECB/PKCS1Padding(1024,2048)RSA/ECB/OAEPWithSHA-1AndMGF1Padding(1024,2048)RSA/ECB/OAEPWithSHA-256AndMGF1Padding(1024,2048)浠ヤ笅鏄竴浜涙爣鍑嗘ā寮忥細浠ヤ笅鏄竴浜涙爣鍑嗗~鍏咃細鍔犲瘑浠g爜濡備笅锛歱rivatestaticfinalStringDES_ALGORITHM="DES";privatestaticfinalStringDES_TRANSFORMATION="DES/ECB/PKCS5Padding";/***DES鍔犲瘑**@paramdataoriginaldata*@paramkeykey*@returnciphertext*/privatestaticbyte[]encryptDES(byte[]data,byte[]key)throwsException{//鑾峰彇DES瀵嗛挜KeysecretKey=getKey(key,DES_ALGORITHM);//閫氳繃鏍囧噯杞崲寰楀埌Cipher瀵硅薄锛岄€氳繃璇ュ璞″畬鎴愬疄闄呯殑鍔犲瘑鎿嶄綔Ciphercipher=Cipher.getInstance(DES_TRANSFORMATION);//閫氳繃鍔犲瘑鏂瑰紡鍜屽瘑閽ュ垵濮嬪寲Cipher瀵硅薄cipher.init(Cipher.ENCRYPT_MODE锛屽瘑閽ワ級锛?/鐢熸垚瀵嗘枃returncipher.doFinal(data);}瑙e瘑浠g爜濡備笅锛歱rivatestaticfinalStringDES_ALGORITHM="DES";privatestaticfinalStringDES_TRANSFORMATION="DES/ECB/PKCS5Padding";/***DES瑙e瘑**@paramdataciphertext*@paramkeykey*@returnoriginaldata*/privatestaticbyte[]decryptDES(byte[]data,byte[]key)throwsException{//鑾峰彇DESKeykeysecretKey=getKey(key,DES_ALGORITHM);//閫氳繃鏍囧噯杞崲寰楀埌Cipher瀵硅薄锛屽苟閫氳繃璇ュ璞″畬鎴愬疄闄呯殑鍔犲瘑鎿嶄綔Ciphercipher=Cipher.getInstance(DES_TRANSFORMATION);//閫氳繃瑙e瘑妯″紡鍜屽瘑閽ュ垵濮嬪寲Cipher瀵硅薄cipher.init(Cipher.DECRYPT_MODE,secretKey);//鐢熸垚鍘熷鏁版嵁returncipher.doFinal(data);}瀹屾暣浠g爜鍜屽畬鏁翠唬鐮佽璁块棶鎴戠殑Github銆傚鏋滃浣犳湁甯姪锛岃缁欐垜涓€涓瓙锛岃阿璋~馃尮馃尮馃尮https://github.com/gozhuyinglong/blog-demos/blob/main/java-source-analysis/src/main/java/io/github/gozhuyinglong/utils/SymmetricKeyUtil.java鎺ㄨ崘闃呰浜嗚В鍗曞悜鍝堝笇鍑芥暟Java鍙嶅皠鏈哄埗锛氳窡鐫€浠g爜瀛︿範鍙嶅皠JDK鍔ㄦ€佷唬鐞嗭細涓嶄粎瑕佸浼氫娇鐢紝鏇磋鎺屾彙鍏跺師鐞?/p>