首页 > 解决方案 > 特殊符号Python上的加解密

问题描述

test = '\x02m@\x0e\x00'
print(test)
print(test.replace('╗m@', "first"))
new_test = test.encode('raw_unicode_escape').decode('utf-8')
print(new_test)
print(new_test.replace('╗m@', "second"))
again_new = new_test.encode('raw_unicode_escape').decode('utf-8')
print(again_new)
print(again_new.replace('╗m@', "third"))

我一直在尝试解密一些最初使用 python 3.6 通过 VB.Net 加密的文件;该文件在编码为 base 64 之前使用公钥加密。我尝试了多种方法来解码 base 64 并使用给定的私钥对其进行解密,但是,我总是会有一些特殊字符,例如“╗m@”即使在我尝试手动删除它们后也无法删除。

我也尝试通过“utf-8”和“ascii”解码,但无济于事。我试过环顾四周,有些人告诉我它看起来像一个双重编码的字符串,但是,即使在解码两次之后,我似乎也无法替换该字符串。

据我所知, '\x02m@\x0e\x00' 在运行时会返回 '╗m@' 。因此,字符串无法直接解码,我使用'raw_unicode_escape'在解码之前将字符串更改为字节对象。

如果有人能指出我应该朝哪个方向前进,将不胜感激。谢谢你。

import Crypto
from Crypto.PublicKey import RSA
import base64
import codecs
import re

# reading private key 
rsa_key = RSA.importKey(open('PrivateKey.pem', 'r').read())

# reading the file that is suppose to be decrypted
file = open('test.txt', 'r')
message = file.read()

# decode base64 first
decrypted_body = base64.b64decode(message)
print(decrypted_body)

# have to make it bytearray if not, it would not be able to concat with the decrypted chunk
final_decrypted = bytearray()

# size of the chunk to decrypt
chunk_size = 128
offset = 0

# maximum length of the body that has to be decrypted
limit = len(decrypted_body)

# there is a need to check the length that has to be decrypted so as to not overshot during the last iteration
while offset < len(decrypted_body):
    if (offset + chunk_size > limit):
        copyLength = limit
    else:
        copyLength = offset + chunk_size

    chunk = decrypted_body[offset: copyLength]

    final_decrypted += rsa_key.decrypt(chunk)

    offset += chunk_size

# decode the result to utf-8 to remove bytes that can't be read
xml_decrypted = codecs.decode(final_decrypted, encoding = 'utf-8', errors = 'ignore')

break_loop = False
remove_arr = []
# pattern to find the special character in what was decoded
pattern = re.compile('[^0-9a-zA-Z<>_=\"?. -/@:™{^\\r}{^\\n}]+')
for i in range(0, len(xml_decrypted)):
    if (pattern.match(xml_decrypted[i])):
        arr = []
        arr.append(xml_decrypted[i])
        # \x00 refer to " " thus, I do not want to remove it as it would make the xml harder to read
        # this is to append all the special symbol into an array 
        while (xml_decrypted[i] != '\x00' and i < len(xml_decrypted)):
            n = i
            i += 1
            if (i < len(xml_decrypted)):
                arr.append(xml_decrypted[i])
            else:
                break_loop = True
                break

        remove_str = "".join(arr)
        remove_arr.append(remove_str)
        i = n
        if (break_loop):
            break

# check if the array has any " " inside as there is no need to remove space from the xml result
# remove each of the result inside the array from the decoded result which will hopefully return me the xml without any special symbol
new_str = ""
remove_arr = [x for x in remove_arr if x != '\x00']
for each in remove_arr:
    print(str(each))
    new_str = xml_decrypted.replace(each, '')
    xml_decrypted = new_str

print(xml_decrypted)

根据要求,我已经在此处发布了我的 python 3 代码,但是我无法发布 VB.Net 代码,因为它不属于我。干杯

标签: python-3.xencryptionutf-8

解决方案


您正在使用原始或教科书 RSA。从decrypt文档中:

注意:此函数执行普通的原始 RSA 解密(教科书)。在实际应用中,您总是需要使用适当的加密填充,并且您不应该使用这种方法直接解密数据。不这样做可能会导致安全漏洞。建议使用模块Crypto.Cipher.PKCS1_OAEPCrypto.Cipher.PKCS1_v1_5代替。

因此,您可能会忘记从结果中删除(很大程度上是随机的)填充。我PKCS1_v1_5先试试。


强烈建议使用混合加密(例如 AES / GCM 与 RSA OAEP 组合),而不是使用相同的 RSA 密钥进行多次加密。


推荐阅读