[英]Cipher.doFinal() returning part of decrypted string for a long string
使用 sunjce 解密字符串時遇到問題:
javax.crypto.Cipher cipher =
javax.crypto.Cipher.getInstance("AES/GCM/NoPadding", new BouncyCastleProvider());
GCMParameterSpec spec = new GCMParameterSpec(Constants.GCM_TAG_BYTES * 8, nonce);
cipher.init(javax.crypto.Cipher.DECRYPT_MODE, dataKey, spec);
cipher.update(ciphertext);
return cipher.doFinal();
如果我將整個密文傳遞給 doFinal,它會正常工作,但如果我正確調用它,它只會返回部分字符串。 例如對於輸入
String jsonExample = "{\"dataType\":\"STRING\",\"strValue\":\"000000\"}";
解密的字節只包含“000000”,但如果我使用
return cipher.doFinal(ciphertext);
並刪除更新,以便正確打印原始字符串。 可能是什么原因? 如果我在更新后將一個空字節數組傳遞給 doFinal,它也會導致相同的數據丟失。 我想知道它背后的邏輯,它適用於小文本,但對於這種大小的文本,它根本不起作用。
這是我的輸入
String jsonExample = "{\"dataType\":\"STRING\",\"strValue\":\"000000\"}";
這就是我打印解密字符串的方式
String decryptedString = new String(decrypted, StandardCharsets.UTF_8);
這就是我將輸入字符串作為字節傳遞給加密 function 的方式
text = jsonExample.getBytes(StandardCharsets.UTF_8)
這就是我調用加密的方式
GCMParameterSpec spec = new GCMParameterSpec(Constants.GCM_TAG_BYTES * 8, nonce);
try {
cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, dek, spec);
byte[] ciphertext = cipher.doFinal(text);
當我在解密過程中使用cipher.update(ciphertext)
后跟cipher.doFinal()
或cipher.doFInal(new byte[0])
它只返回
"000000"
在我使用返回的byte[]
到String decryptedString = new String(decrypted, StandardCharsets.UTF_8);
但是如果我在解密過程中直接調用cipher.doFInal(cipherText)
,我得到的結果字符串就是原始字符串。
您沒有使用 SunJCE,您使用的是 BouncyCastle 提供程序。 (您正在使用 Sun/Oracle API ——JCA,Java 加密體系結構——如果這就是您的意思,而不是提供商SunJCE。)
JCA 中的大多數密碼從每個或任何update
調用(在加密或解密方向)返回部分數據,因此通常如果您使用update
,您必須連接該值(或那些值,如果多次調用)加上從doFinal
返回的任何值,然后再使用任何需要它完成的結果,例如解碼 UTF8。 (通常最簡單的方法是將它們全部ByteArrayOutputStream
.write
或者.put
它們全部寫入ByteBuffer
,但還有其他選擇。)但是 SunJCE 提供者不會為 GCM 執行此操作,僅在解密方向上,顯然是因為spec(SP800-38D)要求認證失敗不釋放明文,只能在.doFinal
時判斷,然后返回所有明文。
Bouncy 提供程序執行“流式”GCM 解密,可以說這違反了規范,但與通常和傳統的 JCA 行為一致,因此大部分數據是從update
調用返回的,只有來自doFinal
的最后幾個字節,您需要連接這些如上所述——或者,正如您所發現的,根本不使用update
:如果數據在加密時都適合一個緩沖區,那么在解密時它也應該適合。
Bouncy 提供者必須緩沖與標簽相等的數據量,以便它可以刪除和驗證所述標簽; 您的代碼工作的“小文本”——因為 decrypt .update
返回任何內容——將達到但不超過您的標簽大小,這顯然是 8 個字節。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.