2

我有一个关于加密和解密字符串的问题

我必须通过网络发送一个加密字符串。(一个 android 应用程序是客户端)这是我到目前为止所做的

byte[] input = getByteArray(filePath);//get the message stored in a file as a byte array

通过阅读一些教程,我设法将字符串消息发送到字节数组并使用 javax.crypto 对其进行加密

Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");

cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);

加密的 msg 被检索为字节数组

byte[] encrypted

我什至设法使用反向方法对其进行解密并再次获取消息

但是当我尝试将此加密的字节数组转换为字符串(通过网络传递它)然后将其重新转换为字节数组时,我的问题就出现了

我试过这个

String encryptedStrn = new String(encrypted); // convert to string

当我通过 byte[] enc = encryptedStrn.getBytes() 将其转换为字节数组时;

并使用此 enc 数组解密,但输出不正确。

我是否错过了一些有关转换的基本内容。请帮我。提前致谢

4

3 回答 3

4

正如 CodeInChaos 在评论中所写,您不应使用String(byte[])构造函数从不透明的二进制数据创建字符串。字符串构造函数用于已使用 ASCII、UTF-8 等编码进行编码的文本数据。不透明的二进制数据(例如加密结果或图像文件)不是以相同方式编码的文本数据,因此您最终丢失信息。

您应该改用 base64,它将任何二进制数据编码为 ASCII。为此有各种 3rd 方库,包括一个很好的公共领域库。或者,在 Android 上,您可以只使用Base64该类。

此外,即使您正在编码或解码真实文本,也不应该使用String.getBytes()andString(byte[])构造函数——它们使用平台默认编码,这几乎总是错误的选择。相反,您应该使用显式采用 aCharSet或字符编码名称的重载。如果您能够控制两端,UTF-8 通常是一种很好的编码 - 如果您只控制一端,您需要知道另一端期望哪种编码。

于 2012-06-30T08:13:17.307 回答
0

您应该对密文进行 base64 编码。不要只是将其转换为字符串。字符串不是二进制数据的容器。

于 2012-06-30T08:13:35.037 回答
0
    public string EncryptUser(string userID)
    {
        using (var cryptoProvider = new DESCryptoServiceProvider())
        using (var memoryStream = new MemoryStream())
        using (var cryptoStream = new CryptoStream(memoryStream, cryptoProvider.CreateEncryptor(DESKey, DESInitializationVector), CryptoStreamMode.Write))
        using (var writer = new StreamWriter(cryptoStream))
        {
            writer.Write(userID);
            writer.Flush();
            cryptoStream.FlushFinalBlock();
            writer.Flush();
            return Convert.ToBase64String(memoryStream.GetBuffer(), 0, (int)memoryStream.Length);
        }
    }


    public string DecryptUserID(string userID)
    {
        using (var cryptoProvider = new DESCryptoServiceProvider())
        using (var memoryStream = new MemoryStream(Convert.FromBase64String(userID)))
        using (var cryptoStream = new CryptoStream(memoryStream, cryptoProvider.CreateDecryptor(DESKey, DESInitializationVector), CryptoStreamMode.Read))
        using (var reader = new StreamReader(cryptoStream))
        {
            return reader.ReadToEnd();
        }
    }
于 2014-04-01T08:20:02.660 回答