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 '################################################'