[英]Why does the Blowfish output in Java and PHP differ by only 2 chars?
我在 PHP 和 JAVA 中有一個河豚加密腳本,反之亦然,直到今天我遇到問題時它工作正常。
相同的內容在 Java 和 PHP 中的加密方式不同,只有 2 個字符,這真的很奇怪。
PHP
wTHzxfxLHdMm/JMFnoh0hciS/JADvFFg
Java
wTHzxfxLHdMm/JMFnoh0hciS/D8DvFFg
-------------------------^^
如您所見,這兩個位置不匹配。 不幸的是,這個值是一個真正的 email 地址,我不能分享它。 我也無法用我測試過的其他幾個值來重現這個問題。 我嘗試在 Java 上更改 Base64 編碼類,但這都沒有幫助。
我能做些什么來解決這個問題?
讓我們看看您的 Java 代碼:
String c = new String(Test.encrypt((new String("thevalue")).getBytes(),
(new String("mykey")).getBytes()));
...
System.out.println("Base64 encoded String:" +
new sun.misc.BASE64Encoder().encode(c.getBytes()));
你在這里做的是:
問題出在第 4 步。它假定任意字節數組表示系統默認編碼中的字符串,並且將此字符串編碼回給出相同的字節 []。 這對某些編碼(例如ISO-8859
系列)有效,但對其他編碼無效。 在 Java 中,當某些字節(或字節序列)在給定的編碼中無法表示時,它將被其他字符替換,稍后再轉換將映射到字節 63(ASCII ?
)。 實際上,文檔甚至說:
當給定字節在默認字符集中無效時,此構造函數的行為未指定。
在您的情況下,根本沒有理由這樣做 - 只需使用您的encrypt
方法直接輸出的字節將它們轉換為 Base64。
byte[] encrypted = Test.encrypt("thevalue".getBytes(),
"mykey".getBytes());
System.out.println("Base64 encoded String:"+ new sun.misc.BASE64Encoder().encode(encrypted));
(另請注意,我在這里刪除了多余的new String("...")
構造函數調用,盡管這與您的問題無關。)
要記住的一點:永遠不要將不是來自編碼字符串的任意字節 [] 轉換為字符串。 Output 的加密算法(和大多數其他加密算法,解密除外)當然屬於不應轉換為字符串的數據類別。
如果您想要可移植的程序,永遠不要使用系統的默認編碼。
你的代碼對我來說似乎是正確的。
看起來您在這些程序之一的輸入中有一個尾隨空格,它只是一個。 我會告訴你為什么:
這些 4 字符塊中的每一個都代表加密字符串中的 3 個字符。 不同的部分(第 7 塊中的 JA 和 D8)實際上來自一個不同的字符。
wTHz xfxL HdMm /JMF noh0 hciS /JAD vFFg
wTHz xfxL HdMm /JMF noh0 hciS /D8D vFFg
如果我做對了,您的 email 地址長度為 19 個字符。 您的一個輸入字符串中的第 20 個字符是一個空格。
問:有沒有試過關聯的PHP解密庫對PHP生成的密文進行解密? 有沒有試過關聯的JAVA解密庫解密JAVA密文?
如果兩者都產生不同的輸出,那么其中一個必須解密失敗。
那是一個 PHP 還是 Java?
無論是哪一個——我都會嘗試用一個可公開共享的字符串來復制另一個這樣的失敗......將該字符串作為單元測試提供給開發人員或開發人員,這些開發人員使用該輪的語言創建加密/解密代碼 -行程加密/解密失敗。
然后……等他們修好。
不確定是否有任何更快的解決方案——除了可能更改加密/解密庫提供程序......或者自己動手......
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.