通过 JSON 发送字节编码数据
Send bytes encoded data over JSON
我正在处理 Python RESTful API 我需要发送字节编码的数据(特别是使用 public RSA 密钥加密的数据通过网络通过 JSON 形式打包 rsa)。
这是它的样子:
>>> import rsa
>>> pubkey, privkey = rsa.newkeys(512, True) # Create a pair of public/private rsa keys ; 512 is for the example
>>> encStr = rsa.encrypt(b"Test string", pubkey) # Encrypt a bytes object using the public key
>>> encStr
b'r\x10\x03e\xc6*\xa8\xb1\xee\xbd\x18\x0f\x7f\xecz\xcex\xabP~\xb3]\x8f)R\x9b>i\x03\xab-m\x0c\x19\xd7\xa5f$\x07\xc1;X\x0b\xaa2\x99\xa8&\xfc/\x9f\x05!nk\x93%\xc0\xf5\x1d\xf8C\x1fo'
"encStr" 是我需要发送的,但是,我不知道它是什么编码,而且包文档也没有提到它。如果您有任何想法,请分享:)
>>> encStr.decode("utf-8")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec cannot decode byte 0x8e in position 0: invalid start byte
>>> encStr.decode("latin1")
'\x8eM\x96Æ\'zÈZ\x89\x85±\x98Z¯Ûzùæ¯;£zñ8\x9b§Ù\x9dÏ\x8eâ0®\x89ó(*?\x92ªg\x12ôsä\x1d\x96\x19\x82\x19-3\x15SBýh"3òÖß\x91Ô' # This could be it
>>> encStr.decode("latin1").encode("latin1")
b'\x8eM\x96\xc6\'z\xc8Z\x89\x85\xb1\x98Z\xaf\xdbz\xf9\xe6\xaf;\xa3z\xf18\x9b\xa7\xd9\x9d\xcf\x8e\xe20\xae\x89\xf3(*?\x92\xaag\x12\xf4s\xe4\x1d\x96\x19\x82\x19-3\x15SB\xfdh"3\xf2\xd6\xdf\x91\xd4' # Nop, garbage
经过一段时间的操作,我找到了一种使用 base64 获取正确字符串的方法。
>>> import base64
>>> b64_encStr = base64.b64encode(encStr)
>>> b64_encStr
b'jk2Wxid6yFqJhbGYWq/bevnmrzujevE4m6fZnc+O4jCuifMoKj+SqmcS9HPkHZYZghktMxVTQv1oIjPy1t+R1A=='
>>> b64_encStr.decode("utf-8")
'jk2Wxid6yFqJhbGYWq/bevnmrzujevE4m6fZnc+O4jCuifMoKj+SqmcS9HPkHZYZghktMxVTQv1oIjPy1t+R1A=='
现在我只需要发送这个,但是,我想知道是否有更有效的方法(更短的字符串;更少的操作,考虑到客户端必须编码和服务器解码,等)。
谢谢!
肖恩
Base64 是一种将字节作为文本发送的相对有效的方法(每个字符 6 位,或者对于普通的单字节字符编码,每个字节 8 位)。这些字节可能有任何值,例如在密文中找到的值。有更高效的编码,例如 basE91,但它们所带来的复杂性几乎没有优势。
但是,我经常看到密文是"stringified"而没有必要。文件、HTTP、套接字等都可以很好地处理任何字节值。如果你想在 GET 请求中使用它,那么你应该使用 base64url 而不是普通的 base 64 编码。开发人员经常对字符串进行不必要的编码,以便可以轻松地在跟踪等中看到这些值,但在这种情况下,只需要对跟踪打印输出本身进行编码。
请注意,我建议您使用 OAEP padding 而不是 PKCS#1 和至少 3072 位的密钥大小,特别是如果您想加密传输的数据而不是加密的数据 "in place".
我正在处理 Python RESTful API 我需要发送字节编码的数据(特别是使用 public RSA 密钥加密的数据通过网络通过 JSON 形式打包 rsa)。
这是它的样子:
>>> import rsa
>>> pubkey, privkey = rsa.newkeys(512, True) # Create a pair of public/private rsa keys ; 512 is for the example
>>> encStr = rsa.encrypt(b"Test string", pubkey) # Encrypt a bytes object using the public key
>>> encStr
b'r\x10\x03e\xc6*\xa8\xb1\xee\xbd\x18\x0f\x7f\xecz\xcex\xabP~\xb3]\x8f)R\x9b>i\x03\xab-m\x0c\x19\xd7\xa5f$\x07\xc1;X\x0b\xaa2\x99\xa8&\xfc/\x9f\x05!nk\x93%\xc0\xf5\x1d\xf8C\x1fo'
"encStr" 是我需要发送的,但是,我不知道它是什么编码,而且包文档也没有提到它。如果您有任何想法,请分享:)
>>> encStr.decode("utf-8")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeDecodeError: 'utf-8' codec cannot decode byte 0x8e in position 0: invalid start byte
>>> encStr.decode("latin1")
'\x8eM\x96Æ\'zÈZ\x89\x85±\x98Z¯Ûzùæ¯;£zñ8\x9b§Ù\x9dÏ\x8eâ0®\x89ó(*?\x92ªg\x12ôsä\x1d\x96\x19\x82\x19-3\x15SBýh"3òÖß\x91Ô' # This could be it
>>> encStr.decode("latin1").encode("latin1")
b'\x8eM\x96\xc6\'z\xc8Z\x89\x85\xb1\x98Z\xaf\xdbz\xf9\xe6\xaf;\xa3z\xf18\x9b\xa7\xd9\x9d\xcf\x8e\xe20\xae\x89\xf3(*?\x92\xaag\x12\xf4s\xe4\x1d\x96\x19\x82\x19-3\x15SB\xfdh"3\xf2\xd6\xdf\x91\xd4' # Nop, garbage
经过一段时间的操作,我找到了一种使用 base64 获取正确字符串的方法。
>>> import base64
>>> b64_encStr = base64.b64encode(encStr)
>>> b64_encStr
b'jk2Wxid6yFqJhbGYWq/bevnmrzujevE4m6fZnc+O4jCuifMoKj+SqmcS9HPkHZYZghktMxVTQv1oIjPy1t+R1A=='
>>> b64_encStr.decode("utf-8")
'jk2Wxid6yFqJhbGYWq/bevnmrzujevE4m6fZnc+O4jCuifMoKj+SqmcS9HPkHZYZghktMxVTQv1oIjPy1t+R1A=='
现在我只需要发送这个,但是,我想知道是否有更有效的方法(更短的字符串;更少的操作,考虑到客户端必须编码和服务器解码,等)。
谢谢!
肖恩
Base64 是一种将字节作为文本发送的相对有效的方法(每个字符 6 位,或者对于普通的单字节字符编码,每个字节 8 位)。这些字节可能有任何值,例如在密文中找到的值。有更高效的编码,例如 basE91,但它们所带来的复杂性几乎没有优势。
但是,我经常看到密文是"stringified"而没有必要。文件、HTTP、套接字等都可以很好地处理任何字节值。如果你想在 GET 请求中使用它,那么你应该使用 base64url 而不是普通的 base 64 编码。开发人员经常对字符串进行不必要的编码,以便可以轻松地在跟踪等中看到这些值,但在这种情况下,只需要对跟踪打印输出本身进行编码。
请注意,我建议您使用 OAEP padding 而不是 PKCS#1 和至少 3072 位的密钥大小,特别是如果您想加密传输的数据而不是加密的数据 "in place".