Mi vedo nella necessità di usare PKI in un programma su Linux.
Il seguente codice riassume l'approccio che prendo.
Genera una coppia di chiavi, memorizzala su disco. La chiave privata è crittografata con AES per la crittografia a riposo (anche la chiave privata non crittografata viene archiviata a scopo di test)
Questo riflette gli standard correnti della comunità di sicurezza?
import os
import json
import base64
import getpass
from Cryptodome.Cipher import AES
from Cryptodome.PublicKey import RSA
print '################################################'
if True:
PASSWORD = '01234567'[:32].ljust(32)
else:
print 'Enter password (max 32 chars)'
PASSWORD = getpass.getpass()[:32].ljust(32)
print '################################################'
GENERATE = False
if not os.path.isfile('private-key-2048.pem.encrypted'):
GENERATE = True
print 'GENERATING KEY PAIR'
print '################################################'
print ' CREATE / LOAD THE PRIVATE KEY'
print '################################################'
if GENERATE:
# store the private key
private_key = RSA.generate(2048)
with open('private-key-2048.pem','wb') as f:
f.write(private_key.exportKey('PEM'))
with open('private-key-2048.pem.encrypted','wb') as f:
cipher = AES.new(PASSWORD, AES.MODE_EAX)
ciphertext, tag = cipher.encrypt_and_digest(private_key.exportKey('PEM'))
print repr(tag)
f.write(json.dumps({
'ciphertext': base64.b64encode(ciphertext),
'nonce': base64.b64encode(cipher.nonce),
'tag': base64.b64encode(tag)
}, indent=1))
else:
# already generated, read the private key
private_key = RSA.importKey(open('private-key-2048.pem','rb').read())
with open('private-key-2048.pem.encrypted','rb') as f:
data = json.loads(f.read())
cipher = AES.new(PASSWORD, AES.MODE_EAX, base64.b64decode(data['nonce']))
ciphertext = cipher.decrypt(base64.b64decode(data['ciphertext']))
try:
cipher.verify(base64.b64decode(data['tag']))
except ValueError:
print 'password incorrect or message corrupted'
private_key = RSA.importKey(ciphertext)
print private_key.exportKey('PEM')
print '################################################'
print ' SAVE / LOAD THE PUBLIC KEY'
print '################################################'
if GENERATE:
# store the public key
public_key = private_key.publickey()
with open('public-key-2048.pem','wb') as f:
f.write(public_key.exportKey('PEM'))
else:
# already generated, read the public key
public_key = RSA.importKey(open('public-key-2048.pem','rb').read())
print public_key.exportKey('PEM')
print '################################################'
print ' ENCRYPT WITH PUBLIC KEY'
print '################################################'
from Cryptodome.Cipher import PKCS1_OAEP
encryptor = PKCS1_OAEP.new(public_key)
encrypted = encryptor.encrypt('this is a test')
print repr(encrypted)
print '################################################'
print ' DECRYPT WITH PRIVATE KEY'
print '################################################'
decryptor = PKCS1_OAEP.new(private_key)
decrypted = decryptor.decrypt(encrypted)
print decrypted
print '################################################'