Me veo en la necesidad de usar PKI en un programa en Linux.
El siguiente código resume el enfoque que tomaría.
Genere un par de claves, guárdelo en el disco. La clave privada se encripta con AES para el cifrado en reposo (la clave privada sin cifrar también se almacena con fines de prueba)
¿Esto refleja los estándares actuales de la comunidad de seguridad?
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 '################################################'