亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Java 中的 AES 加密以匹配 C# 輸出

Java 中的 AES 加密以匹配 C# 輸出

C#
www說 2022-10-15 14:06:46
我正在嘗試使用 JAVA 進行 AES 加密,我進行了多次嘗試,嘗試了很多代碼并進行了許多更改,最終達到了我的加密文本與使用 C# 代碼生成的加密文本匹配但部分匹配的地方。最后一個 32 位塊是不同的。我無權訪問 C# 代碼,因為它是第 3 方服務。誰能指導我錯過了什么?提到的條件是使用:在 CBC 模式下使用 256 位 AES 加密并使用 PKCS5 填充使用您的主鍵和初始化向量來加密整個查詢字符串。(不要在查詢字符串中包含消息摘要。)主鍵是 64 位十六進制字符串,初始化向量是 32 位十六進制字符串。我使用的樣本值是:Aes_IV = 50B666ADBAEDC14C3401E82CD6696D4Aes_Key = D4612601EDAF9B0852FC0641DC2F273E0F2B9D6E85EBF3833764BF80E09DD89F(我的密鑰材料)Plain_Text = ss=brock&pw=123456&ts=20190304234431(輸入)Encrypted_Text = 7643C7B400B9A6A2AD0FCFC40AC1B11E51A038A32C84E5560D92C0C49B3B7E0 A072AF44AADB62FA66F047EACA5C6A018(輸出)我的輸出= 7643C7B400B9A6A2AD0FCFC40AC1B11E51A038A32C84E5560D92C0C49B3B7E0 A38E71E5C846BAA6C31F996AB05AFD089public static String encrypt( String keyMaterial, String unencryptedString, String ivString ) {    String encryptedString = "";    Cipher cipher;    try {        byte[] secretKey = hexStrToByteArray( keyMaterial );        SecretKey key = new SecretKeySpec( secretKey, "AES" );        cipher = Cipher.getInstance( "AES/CBC/PKCS5Padding" );        IvParameterSpec iv;        iv = new IvParameterSpec( hexStrToByteArray( ivString ) );        cipher.init( Cipher.ENCRYPT_MODE, key, iv );        byte[] plainText = unencryptedString.getBytes( "UTF-8") ;        byte[] encryptedText = cipher.doFinal( plainText );        encryptedString = URLEncoder.encode(byteArrayToHexString( encryptedText ),"UTF-8");    }    catch( InvalidKeyException | InvalidAlgorithmParameterException | UnsupportedEncodingException | IllegalBlockSizeException | BadPaddingException | NoSuchAlgorithmException | NoSuchPaddingException e ) {        System.out.println( "Exception=" +e.toString() );    }    return encryptedString;}任何建議,我應該怎么做才能匹配輸出?
查看完整描述

1 回答

?
小怪獸愛吃肉

TA貢獻1852條經驗 獲得超1個贊

如果只有 ECB / CBC 填充的最后一個塊不同,那么您可以很確定使用了不同的塊密碼填充。要驗證使用了哪個填充,您可以嘗試(正如 Topaco 在問題下方的評論中所做的那樣),或者您可以在沒有填充的情況下解密密文。對于 Java,那將是"AES/CBC/NoPadding".

因此,如果您在給定密鑰(和 IV)的情況下這樣做,那么您將獲得以下十六進制輸出:

73733D62726F636B2670773D3132333435362674733D3230313930333034323334343331000000000000000000000000

顯然這是零填充。

零填充有一個很大的缺點:如果您的密文以值為零的字節結尾,那么這個字節可能會被視為填充并從結果中刪除。通常這對于由 ASCII 或 UTF-8 字符串組成的純文本來說不是問題,但對于二進制輸出可能會比較棘手。當然,我們在這里假設字符串不使用預期會出現在加密明文中的空終止符。

還有另一個較小的缺點:如果您的明文恰好是塊大小,那么零填充就足夠不標準了,因此有兩種情況:

  1. 填充總是被應用并且需要被刪除,這意味著如果明文大小正好是塊大小的數倍,那么仍然會添加一個完整的填充塊(所以對于 AES,你會有 1..16 零值字節作為填充);

  2. 僅在嚴格要求時才應用填充,這意味著如果明文大小正好是塊大小的數倍,則不應用填充(因此對于 AES,您將有 0..15 個零值字節作為填充)。

因此,目前,對于加密,您可能必須測試預期/接受哪一個。例如,可用于 C# 和 Java 的 Bouncy Castle 總是(未)填充,而可怕的 PHP / mcrypt 庫只在需要的地方填充。

當然,您始終可以執行自己的填充,然后"NoPadding"用于 Java。請記住,您永遠不會取消填充超過 16 個字節。

一般警告:未經身份驗證的加密不適合傳輸模式安全性。


查看完整回答
反對 回復 2022-10-15
  • 1 回答
  • 0 關注
  • 153 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號