我有关于加密和解密字符串的问题
我必须通过网络发送一个加密的字符串。(一个Android应用程序是客户端)这是我到目前为止所做的
byte[] input = getByteArray(filePath);//get the message stored in a file as a byte array
通过浏览一些教程,我设法将String消息传递给字节数组并且 使用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数组进行解密,但输出无法正确显示。
我是否错过了一些有关转换的基本内容。请帮我。 提前谢谢
答案 0 :(得分:4)
正如CodeInChaos在评论中所写,您不应该使用String(byte[])
构造函数从不透明的二进制数据创建字符串。字符串构造函数用于文本数据,它使用ASCII,UTF-8等编码进行编码。不透明的二进制数据(如加密结果或图像文件) not 以相同的方式编码文本数据,因此您最终会丢失信息。
您应该使用base64,它将任何二进制数据编码为ASCII。这有各种第三方库,包括一个好的public domain one。或者,在Android上,您只需使用Base64
类。
此外,即使您 编码或解码真实文本,也不应该使用String.getBytes()
和String(byte[])
构造函数 - 它们使用平台默认编码,几乎总是错误的选择。相反,您应该使用明确采用CharSet
或字符编码名称的重载。如果你能够控制两端,UTF-8通常是一个很好的编码 - 如果你只控制一端,你需要知道另一端期望的编码。
答案 1 :(得分:0)
您应该对密文进行base64编码。不要只是将它转换为String。 String不是二进制数据的容器。
答案 2 :(得分: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();
}
}