我有两面:
全部运行: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"
在填充程序中,客户端和服务器之间似乎存在丢失(或添加??)。但对于我的生活,我不知道它会是什么。 我怀疑加密完成的方式客户端可能是罪魁祸首,就像在本地完成一样,一切都完美无瑕。
由于