避免加密和编码的URL字符串中的换行符

时间:2012-04-23 14:30:54

标签: java encryption

我正在尝试实现一个简单的字符串编码器来混淆URL字符串的某些部分(以防止它们被用户弄乱)。我使用的代码几乎与JCA guide中的示例完全相同,除了:

  • 使用DES(假设它比AES快一点,并且需要更小的密钥)和
  • Base64 zh_ /解码字符串以确保它对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);

4 个答案:

答案 0 :(得分:12)

只需执行base64Str = base64Str.replaceAll("(?:\\r\\n|\\n\\r|\\n|\\r)", "") 在编码的字符串上。

当您尝试将其解码回字节时,它可以正常工作。我用随机生成的字节数组测试了几次。显然,解码过程只是忽略它们存在或不存在的换行符。 我使用com.sun.org.apache.xml.internal.security.utils.Base64测试了这个“确认工作” 其他未经测试的编码器。

答案 1 :(得分:7)

Base64编码器通常会施加一些最大行( chunk )长度,并在必要时添加换行符。您通常可以配置它,但这取决于特定的编码器实现。 例如,Apache Commons中的类具有linelength属性,将其设置为零(或负数)会禁用行分隔。

顺便说一句:我同意另一个答案,即今天的DES几乎不可取。此外,你只是“混淆”或真正加密?谁有钥匙?整件事对我来说都不是很好。

答案 2 :(得分:2)

来自VA的编码片段......

替换:

return new BASE64Encoder().encode(encVal);

with:

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

删除我们的结果中的换行符

import android.util.Base64;

...

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

答案 3 :(得分:1)

虽然它与您的实际问题无关,但DES通常比AES(至少在软件中)更慢,所以除非你真的需要保持密钥小,AES几乎可以肯定是一个更好的选择。

其次,加密(DES或AES)将在其输出中产生新行字符是完全正常的。在没有它们的情况下生成输出将完全取决于base-64编码器,因此您需要查看它。

在输出中看到base-64以固定间隔插入新行字符并不特别令人惊讶。 base-64编码的最常见用途是将原始数据放入类似电子邮件正文的内容中,其中很长的行会导致问题。为了防止这种情况,数据被分解成碎片,通常不超过80列(通常少一些)。在这种情况下,新行应该被忽略,因此,如果内存服务,你应该能够删除它们。