当从android调用时,TripleDES算法会生成不同的结果

时间:2011-09-27 16:51:05

标签: java android encoding tripledes

我有一个简单的java web应用程序,由apache wicket构建。当我在Web应用程序中注册用户时,我使用三元组加密他们输入的密码并将其保存到数据库。在登录页面输入相同的密码时,我对其进行加密并将加密的密码传递给数据库,以检查它是否正确。

现在我正在构建一个具有相同登录功能的Android应用程序。

在Android应用程序登录页面中我使用相同的加密库来加密密码,我使用相同的密钥和初始化向量两个平台,但如果我尝试在android中输入相同的密码字符串,TripleDes算法生成完全不同的加密密码(更长)。因此从Android设备登录失败。我还注意到,android生成的加密密码无法解密,它会引发异常。

我认为两个平台之间可能存在字符串编码问题差异,但无法弄清楚是什么原因以及如何解决它。

这是我使用的算法:

public class TripleDES {
private String key;
private byte[] initializationVector;

public TripleDES(String key, byte[] initializationVector)
{
    this.key = key;
    this.initializationVector = initializationVector;
}

public String encryptText(String plainText) throws Exception{
//----  Use specified 3DES key and IV from other source -------------------------
  byte[] plaintext = plainText.getBytes();
  byte[] tdesKeyData = key.getBytes();

  System.out.println("plain text length: " + plaintext.length);
  System.out.println("key length: " + tdesKeyData.length);


  Cipher c3des = Cipher.getInstance("DESede/CBC/PKCS5Padding");
  SecretKeySpec    myKey = new SecretKeySpec(tdesKeyData, "DESede");
  IvParameterSpec ivspec = new IvParameterSpec(initializationVector);

  c3des.init(Cipher.ENCRYPT_MODE, myKey, ivspec);
  byte[] cipherText = c3des.doFinal(plaintext);

  return Base64Coder.encodeString(new String(cipherText));
}

public String decryptText(String encryptedText) throws Exception{
    //----  Use specified 3DES key and IV from other source -------------------
      byte[] enctext = Base64Coder.decode(encryptedText);
      byte[] tdesKeyData = key.getBytes();


      Cipher c3des = Cipher.getInstance("DESede/CBC/PKCS5Padding");
      SecretKeySpec    myKey = new SecretKeySpec(tdesKeyData, "DESede");
      IvParameterSpec ivspec = new IvParameterSpec(initializationVector);

      c3des.init(Cipher.DECRYPT_MODE, myKey, ivspec);
      byte[] cipherText = c3des.doFinal(enctext);
      return new String(cipherText);
    }

}

1 个答案:

答案 0 :(得分:2)

(编辑:如上所述,以可逆方式存储密码是一个坏主意,但为了使加密部分正确...)

这是第一个问题:

byte[] plaintext = plainText.getBytes();
byte[] tdesKeyData = key.getBytes();

那是使用默认的系统字符编码。在所有Android手机上都一样吗?我不知道。在Android中和在Web服务器上是一样的吗?我不知道。如果一个平台使用UTF-16而另一个平台使用UTF-8且plainText都是ASCII,那肯定会导致加密数据大小的两倍差异。

我建议始终指定编码 - 在许多情况下,“UTF-8”是一个不错的选择。

编辑:好的,看起来问题是您之后使用cipherText做了什么。您需要将原始字节转换为base64字符串。 Android内置了base64编码器,但this public domain code应该可以正常工作。而不是这一行:

return Base64Coder.encodeString(new String(cipherText));

你会用

return Base64.encodeBytes(cipherText);