在不同的编程语言之间传递加密数据的最佳做法 [英] Best practices for passing encrypted data between different programming languages

查看:203
本文介绍了在不同的编程语言之间传递加密数据的最佳做法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经读过,如果你想使用一种编程语言加密一个字符串,并使用另一种编程语言解密该字符串,那么为了确保兼容性,最好在进行加密之前进行一些转换。我已经看到,加密字符串的字节数组而不是字符串本身是最好的做法。另外,我已经看到,某些加密算法期望每个加密的数据包是一个固定长度的大小。如果要加密的最后一个数据包不是所需的大小,则加密将失败。因此,加密首先被转换为固定长度的数据(如十六进制)似乎是一个好主意。



我正在尝试识别通常有用的最佳做法,无论使用的加密算法如何。为了在不同语言和平台上对数据进行加密和解密时最大程度地实现兼容性,我希望对以下步骤进行批评:



加密:




  • 以纯文本字符串开头

  • 将纯文本字符串转换为字节数组
  • 将字节数组转换为十六进制

  • 将hex加密为加密字符串

  • 以加密字符串结尾



解密:




  • 开始加密的字符串

  • 将加密的字符串解密为十六进制

  • 将十六进制转换为字节数组

  • 转换字节数组以纯文本字符串

  • 以纯文本字符串结尾


解决方案

你的前提是正确的,但在某些方面它比这更容易一些。现代加密算法的意义在于语言不可知,只要您具有相同的输入与相同的键,您应该获得相同的结果。



这是真的,对于大多数密码和一些模式,数据需要固定长度。转换为十六进制不会这样做,因为数据需要以固定边界结束。以AES为例,如果要加密4个字节,则需要将其填充到16个字节,这是一个十六进制表示形式。幸运的是,最有可能发生在最终使用的加密API中,使用标准的填充方案。由于您没有标记语言,这里是一个列表 .NET支持的AesManaged类的填充模式。



另一方面,正确加密数据需要的不仅仅是字节编码。您需要选择正确的操作模式(首选CBC或点击率),然后提供某种类型的消息完整性。单独加密不能防止篡改数据。如果你想简化一些事情,那么看一下像 GCM 那样的模式既保密又诚信。



您的方案应该如下所示:




  • 将纯文本转换为字符串到字节数组。请参阅@ rossum的关于字符编码的重要注释的评论。

  • 生成随机对称密钥,或使用 PBKDF2 转换密钥的密码

  • 生成一个用于GCM的随机IV /随机数

  • 加密字节数组并存储它,以及验证标签

  • 您可以选择将字节数组存储为 Base64 string



解密:




  • 如果你将字节数组存储为Base64字符串,转换回到字节数组。

  • 将加密的字节数组解密为明文

  • 验证生成的认证标签与存储的认证标签匹配

  • 转换字节数组为纯文本字符串。


I have read that if you want to encrypt a string using one programming language and decrypt that string using another programming language, then to ensure compatibility it is best to do some conversions prior to doing the encryption. I have read that it's a best practice to encrypt the byte array of a string rather than the string itself. Also, I have read that certain encryption algorithms expect each encrypted packet to be a fixed length in size. If the last packet to be encrypted isn't the required size, then encryption would fail. Therefore it seems like a good idea to encrypt data that has first been converted into a fixed length, such as hex.

I am trying to identify best practices that are generally useful regardless of the encryption algorithm being used. To maximize compatibility when encrypting and decrypting data across different languages and platforms, I would like a critique on the following steps as a process:

Encryption:

  • start with a plain text string
  • convert plain text string to byte array
  • convert byte array to hex
  • encrypt hex to encrypted string
  • end with an encrypted string

Decryption:

  • start with an encrypted string
  • decrypt encrypted string to hex
  • convert hex to byte array
  • convert byte array to plain text string
  • end with a plain text string

解决方案

Your premise is correct, but in some ways it's a little easier than that. Modern crypto algorithms are meant to be language agnostic, and provided you have identical inputs with identical keys, you should get identical results.

It's true that for most ciphers and some modes, data needs to be a fixed length. Converting to hex won't do it, because the data needs to end on fixed boundaries. With AES for example, if you want to encrypt 4 bytes, you'll need to pad it out to 16 bytes, which a hex representation wouldn't do. Fortunately that'll most likely happen within the crypto API you end up using, with one of the standard padding schemes. Since you didn't tag a language, here's a list of padding modes that the AesManaged class in .NET supports.

On the flip side, encrypting data properly requires a lot more than just byte encoding. You need to choose the correct mode of operation (CBC or CTR is preferred), and then provide some type of message integrity. Encryption alone doesn't protect against tampering with data. If you want to simplify things a bit, then look at a mode like GCM, which handles both confidentiality, and integrity.

Your scheme should then look something like:

  • Convert plain text to string to byte array. See @rossum's comment for an important note about character encoding.
  • Generate a random symmetric key or use PBKDF2 to convert a passphrase to a key
  • Generate a random IV/nonce for use with GCM
  • Encrypt the byte array and store it, along with the Authentication Tag
  • You might optionally want to store the byte array as a Base64 string.

For decryption:

  • If you stored the byte array as a Base64 string, convert back to the byte array.
  • Decrypt encrypted byte array to plaintext
  • Verify the resulting Authentication Tag matches the stored Authentication Tag
  • Convert byte array to plain text string.

这篇关于在不同的编程语言之间传递加密数据的最佳做法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆