2012-04-23 72 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