2012-04-23 82 views
5

我想實現一個簡單的字符串編碼器來模糊URL字符串的某些部分(以防止它們被用戶弄糊塗)。我使用的代碼幾乎相同的樣品中的JCA guide,不同的是:使用DES避免在加密和編碼的URL字符串中換行

  • (假設它比AES快一點,需要一個較小的鍵)
  • 的Base64 EN /串來解碼確保它對URL保持安全。

由於我無法理解的原因,輸出字符串以換行符結束,我認爲這是行不通的。我無法弄清楚是什麼原因造成的。對類似的東西更容易的建議或指向其他資源的閱讀?我發現所有的密碼引用都超出了我的想象(而且過度殺傷),但是一個簡單的ROT13實現將不起作用,因爲我想處理更大的字符集(並且不想浪費時間來實現可能的有我不認爲的模糊人物的問題)。

樣品輸入(無斷線):

http://maps.google.com/maps?q=kansas&hl=en&sll=42.358431,-71.059773&sspn=0.415552,0.718918&hnear=Kansas&t=m&z=7 

樣本輸出(換行如下所示):

GstikIiULcJSGEU2NWNTpyucSWUFENptYk4m5lD8RJl8l1CuspiuXiE9a07fUEAGM/tC7h0Vzus+ 
jAH6cT4Wtz2RUlBdGf8WtQxVDKZVOzKwi84eQh2kZT9T3KomlnPOu2owJ/2RAEvG+QuGem5UGw== 

我的編碼片段:

final Key key = new SecretKeySpec(seed.getBytes(), "DES"); 
final Cipher c = Cipher.getInstance("DES"); 
c.init(Cipher.ENCRYPT_MODE, key); 
final byte[] encVal = c.doFinal(s.getBytes()); 
return new BASE64Encoder().encode(encVal); 
+1

你是否試圖恢復你的編碼操作,看看是否有用 ? – Snicolas 2012-04-23 14:34:05

+0

BASE64Encoder類從哪裏來? – leonbloy 2012-04-23 14:38:43

+1

@leonbloy我正在導入sun.misc.BASE64Decoder,我發現感謝[這篇文章](http://stackoverflow.com/questions/2267036/work-sun-misc-base64encoder-decoder-for-getting-字節)不是一個好主意。 – milletron 2012-04-23 15:30:03

回答

7

Base64的通常編碼器施加一些最大線()的長度,並添加換行符時cessary。你通常可以配置,但這取決於特定的編碼器實現。 例如,Apache Commons中的類具有linelength屬性,將其設置爲零(或負值)將禁用行分隔。

順便說一句:我同意另一個答案,因爲DES是不可取的今天。此外,你只是「混淆」或真正加密?誰有鑰匙?整件事對我來說都不是很好。

+0

上找到另一種輕量級的開源實現。它比加密更加混淆。只需在調用類中使用硬編碼字符串作爲「鍵」(由生成和使用混淆的URL的servlet共享)。感謝行長領先,也由@Jerry Coffin – milletron 2012-04-23 15:35:32

+0

指出0123由於Apache Commons編碼器陳述爲「......它只是編碼/解碼與較低的127 ASCII圖表兼容的編碼/解碼字符編碼」,因此贏得了「因爲我會有超出這個範圍的角色,所以無法工作。我想,需要重新考慮整個方法。 – milletron 2012-04-23 15:41:30

+0

「這將無法正常工作,因爲我的字符超出此範圍」:仔細閱讀:它適用於ASCII以外的字符,它只是二進制編碼不能是utf-16,但它可以是utf-8,或者ISO-8859-1等 – leonbloy 2012-04-23 15:45:33

1

雖然它無關你的實際問題,DES一般比AES(至少在軟件),所以除非你真的需要保持重點小,AES幾乎可以肯定是一個更好的選擇。其次,加密(DES或AES)在其輸出中會產生新行字符是非常正常的。沒有它們的情況下生成輸出將完全取決於base-64編碼器,因此這是您顯然需要查看的地方。

雖然看到base-64在其輸出中定期插入換行字符並不特別令人驚訝。 base-64編碼最常見的用途是將原始數據放入類似電子郵件正文的內容中,其中很長的一行會導致問題。爲了防止這種情況發生,數據被分解成小塊,通常不超過80列(通常少一些)。在這種情況下,新行應該被忽略,所以你應該能夠刪除它們,如果內存服務的話。

11

只需對編碼字符串執行base64Str = base64Str.replaceAll("(?:\\r\\n|\\n\\r|\\n|\\r)", "") 即可。

當你嘗試將它解碼回字節時,它工作正常。我用隨機生成的字節數組測試過幾次。顯然,解碼過程忽略了新行,無論它們是否存在。 我通過使用com.sun.org.apache.xml.internal.security.utils.Base64 測試了這個「確認工作」。其他編碼器未經測試。

+2

這個答案超級棒,希望我能夠upvote 10次。 – 2014-06-17 02:40:24

+1

良好的做法與否,有人應該評論,但你救了我的一天先生謝謝 – dakait 2016-01-05 11:42:00

+0

太棒了。使用一個快速的私有工具,這使我不必再停下來找到第三方的Base64編碼器。 – developerwjk 2016-03-30 22:12:00

1

從VA的編碼片段...

取代:

return new BASE64Encoder().encode(encVal); 

有:

return new android.util.Base64.encodeToString(encVal, Base64.NO_WRAP); 

刪除線斷了我們的結果

import android.util.Base64; 

... 

return new BASE64.encodeToString(encVal, Base64.NO_WRAP); 
+0

你能詳細解釋一下你的答案嗎? – 2016-06-08 11:18:35

+0

從VA的編碼片段中,我們替換「return new BASE64Encoder()。encode(encVal);」與「返回新的android.util.Base64.encodeToString(encVal,Base64.NO_WRAP);」從我們的結果中刪除折線。 – user2955935 2016-06-09 02:49:57