PyCrypto加密/解密错误客户端/服务器和CHIL引擎

时间:2018-01-29 23:24:00

标签: django python-2.7 encryption public-key-encryption pycrypto

我有两面:

  • 一个或多个客户端,运行Python 2.7.10,Pycrypto 2.6.1
  • 一台服务器,运行相同的
  • 全部运行:django 1.11.2,Centos 6.9,OpenSSL 1.0.1e-fips

  • 服务器持有HSM支持的私钥和相应的公钥。

  • 客户端可以使用公钥,并在将加密数据发送到服务器之前使用它进行加密。

要加密的客户端代码:

from Crypto.Cipher import PKCS1_OAEP
from Crypto.PublicKey import RSA
from Crypto.Hash import SHA256


def encrypt_RSA(public_key_loc, clear_text):
    key = open(public_key_loc, "r").read()
    rsakey = RSA.importKey(key)
    cipher = PKCS1_OAEP.new(rsakey, hashAlgo=SHA256)
    encrypted = cipher.encrypt(clear_text)
    return encrypted.encode('base64')

要发送的客户端代码:

import json
import requests
from .crypt import encrypt_RSA

r = requests.post(
    settings.THE_URL,
    data=json.dumps({
        'text': encrypt_RSA(settings.PUBLIC_KEY, 'clear text'),
    }),
    headers={'content-type': 'application/json'},
    timeout=5
)

这很有效 - 显然。

当收到服务器端时,会发生以下情况:

engine "chil" set.
RSA operation error
140648313706312:error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is not 02:rsa_pk1.c:190:
140648313706312:error:04065072:rsa routines:RSA_EAY_PRIVATE_DECRYPT:padding check failed:rsa_eay.c:674:

这是在经过django REST框架等验证器层之后的代码处理解密。

def decrypt_RSA_CHIL(private_key_loc, encrypted_text):

    print private_key_loc

    print '######### BEFORE ##########'
    print encrypted_text
    encrypted_text = base64.b64decode(encrypted_text)
    print '######### AFTER ##########'
    print encrypted_text

    # after checking those temp files, they have a proper size of 256 byte
    # so it seems they are indeed padded
    encrypted_text_location = '/tmp/encrypted_' + str(uuid.uuid4())

    print encrypted_text_location

    f = open(encrypted_text_location, 'w')
    f.write(encrypted_text)
    f.close()

    # Running the decryption command
    result = execute(
        [
            '/opt/nfast/bin/preload /usr/bin/openssl rsautl -engine chil -decrypt -inkey '
            + str(private_key_loc) + ' -in ' + encrypted_text_location
        ],
        '/tmp'
    )
    print result

    # removing the file with encrypted data from file system
    os.remove(encrypted_text_location)

    stdout_list = result[1].split("\n") if result[1] else []

    print stdout_list

    if result[0] is False and stdout_list and result[2] == u'engine "chil" set.\n':
        return stdout_list[0]
    else:
        pass

    return None

execute方法(很久以前在互联网上的某个地方找到并且到目前为止工作正常):

import subprocess

def execute(cmd_array, working_dir):

    stdout = ''
    stderr = ''

    try:
        try:
            process = subprocess.Popen(
                cmd_array,
                cwd=working_dir,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                bufsize=1,
                shell=True,
            )
        except OSError as e:
            return [False, '', 'ERROR : command(' + ' '.join(cmd_array) + ') could not get executed!']

        for line in iter(process.stdout.readline, b''):

            try:
                echo_line = line.decode("utf-8")
            except:
                echo_line = str(line)

            stdout += echo_line

        for line in iter(process.stderr.readline, b''):

            try:
                echo_line = line.decode("utf-8")
            except:
                echo_line = str(line)

            stderr += echo_line.decode()

    except (KeyboardInterrupt, SystemExit) as err:
        return [False, '', str(err)]

    process.stdout.close()

    return_code = process.wait()
    if return_code != 0 or stderr != '':
        return [False, stdout, stderr]
    else:
        return [True, stdout, stderr]

现在我知道 HSM(相对低端型号) 工作:

> sudo /opt/nfast/bin/generatekey embed name=PRIVKEYNAME cardset=Keymanager
# answer a few questions
# private key saved in /tmp/KEY

> sudo openssl rsa -in /tmp/KEY -pubout > /tmp/KEY.pub
# generates the public key

> sudo cat /tmp/clear.txt | openssl rsautl -encrypt -pubin -inkey veeip2.pub > /tmp/encrypted.txt
# "clear.txt" contains "foo"
# "encrypted.txt" is always 256 bytes long, which is correct.

> sudo /opt/nfast/bin/preload /usr/bin/openssl rsautl -engine chil -decrypt -inkey /tmp/KEY -in /tmp/encrypted.txt
# engine "chil" set.
# "foo"

在填充程序中,客户端和服务器之间似乎存在丢失(或添加??)。但对于我的生活,我不知道它会是什么。 我怀疑加密完成的方式客户端可能是罪魁祸首,就像在本地完成一样,一切都完美无瑕。

由于

0 个答案:

没有答案