
開発者の義務により、タスクはPEM形式の公開キーと秘密キーを使用してRSAアルゴリズムでテキスト文字列を暗号化することでした。 この問題を研究するとき、選択はOpenSSLライブラリの使用に依存していました。 Delphiでの暗号化機能の実装例を共有したいと思います。 アクションは、Windows、Borland Delphi 7開発環境で実行されました。
どこから始めますか?
まず、opensslパッケージ、またはlibeay32.dllライブラリが必要です。 ライブラリを接続するには、プロジェクトに接続する必要のある既製のユニット
libeay32.pasが必要です。 私の例では、プロジェクトからキーを生成する機能はありません。これを行う方法は、記事の下部にあるリンクの資料で読むことができます。 キーペアを生成するには、cmdから次のコマンドを使用して自分でopensslを使用しました。
秘密鍵を生成し、そこから公開鍵を抽出しますopenssl genrsa 1024 > private.pem openssl rsa -in private.pem -pubout > public.pem
ここで、1024はキービットサイズです。 暗号化のための文字列の長さは、キーのビット数にも依存することに注意してください。 キーが1024ビットの場合、キーのサイズと同じサイズである128バイトのみを暗号化できます。 以下に、RSAキー構造のサイズを決定する関数を示します。 しかし、それだけではありません。 暗号化中に
パディングパラメータを指定すると、このバッファは11バイト減少します。
パディングパラメータは、データのアライメントを担当します
-PKCS#1 。
2048ビットのキーを生成すると、256バイトを暗号化できます。 これにより、1バイトしか暗号化されていなくても、出力暗号文のサイズが大きくなります。
私のタスクでは、117バイトで十分でした。カードデータが収まり、データベース内の行のサイズはもちろん大幅に増加しました。 しかし、それにはセキュリティが必要です。
主な機能
暗号化に使用する主なものは次のとおりです。
暗号化機能の初期化
OpenSSL_add_all_algorithms; OpenSSL_add_all_ciphers; OpenSSL_add_all_digests; ERR_load_crypto_strings; ERR_load_RSA_strings;
破壊する
EVP_cleanup; ERR_free_strings;
読書キー
暗号化/復号化機能
さあ始めましょう
したがって、生成されたキーがあり、dllはプロジェクトフォルダーにあり、liblea32.pasはuseに接続されています。 openssl初期化手順を呼び出します。
procedure LoadSSL; begin OpenSSL_add_all_algorithms; OpenSSL_add_all_ciphers; OpenSSL_add_all_digests; ERR_load_crypto_strings; ERR_load_RSA_strings; end; procedure FreeSSL; begin EVP_cleanup; ERR_free_strings; end;
キー読み込み関数を作成します。
KeyFile-キーに任せる( 'C:\ key.pem'):
function LoadPublicKey(KeyFile: string) :pEVP_PKEY ; var mem: pBIO; k: pEVP_PKEY; begin k:=nil; mem := BIO_new(BIO_s_file());
キー読み取り関数の呼び出しとエラー処理
var FPublicKey: pEVP_PKEY; FPrivateKey: pEVP_PKEY; err: Cardinal; … FPublicKey := LoadPublicKey('C:\public.key'); FPrivateKey := LoadPrivateKey('C:\private.key');
暗号化(公開鍵)
var rsa: pRSA;
復号化(秘密鍵)
var rsa: pRSA; out_: AnsiString; str, data: PAnsiChar; len, b64len: Integer; penc64: PAnsiChar; b64, mem, bio_out, bio: pBIO; size: Integer; err: Cardinal; begin
結論として、アプリケーションで「有線」キーを読み取る例
この例は、秘密鍵とその読み取りを示しています。これは「縫い合わせ」られており、公開鍵は
PEM_read_bio_PUBKEY関数によって読み取られます
var mem, keybio: pBIO; k: pEVP_PKEY; keystring: AnsiString; begin keystring := '-----BEGIN RSA PRIVATE KEY-----' + #10 + 'MIICXgIBAAKBgQCfydli2u2kJfb2WetkOekjzQIg7bIuU7AzAlBUPuA72UYXWnQ/' + #10 + 'XcdSzEEMWSBLP7FO1vyVXR4Eb0/WqthF0ZViOK5bCN9CnR/1GMMiSqmIdByv/gUe' + #10 + 'Z/UjGrKmxeQOoa2Yt0MJC64cNXgnKmYC7ui3A12LlvNdBBEF3WpcDbv+PQIDAQAB' + #10 + 'AoGBAJnxukKHchSHjxthHmv9byRSyw42c0g20LcUL5g6y4Zdmi29s+moy/R1XOYs' + #10 + 'p/RXdNfkQI0WnWjgZScIij0Z4rSs39uh7eQ5qxK+NH3QIWeR2ZNIno9jAXPn2bkQ' + #10 + 'odS8FPzbZM9wHhpRvKW4FNPXqTc3ZkTcxi4zOwOdlECf9G+BAkEAzsJHgW1Isyac' + #10 + 'I61MDu2qjMUwOdOBYS8GwEBfi/vbn/duwZIBXG/BZ7Pn+cBwImfksEXwx0MTkgF3' + #10 + 'gyaChUSu+QJBAMXX3d94TwcF7lG9zkzc+AR/Onl4Z5UAb1GmUV57oYIFVgW1RIOk' + #10 + 'vqynXWrTjTOg9C9j+VEpBG67LcnkwU16JmUCQH7pukKz9kAhnw43PcycDmhCUgvs' + #10 + 'zCn/V8GCwiOHAZT7qLyhBrzazHj/cZFYknxMEZAyHk3x2n1w8Q9MACoVsuECQQDF' + #10 + 'U7cyara31IyM7vlS5JpjMdrKyPLXRKXDFFXYHQtLubLA4rlBbBHZ9txP7kzJj+G9' + #10 + 'WsOS1YxcPUlAM28xrYGZAkEArVKJHX4dF8UUtfvyv78muXJZNXTwmaaFy02xjtR5' + #10 + 'uXWT1QjVN2a6jv6AW7ukXiSoE/spgfvdoriMk2JSs88nUw==' + #10 + '-----END RSA PRIVATE KEY-----' ; k := nil; keybio := BIO_new_mem_buf(Pchar(keystring), -1); mem := BIO_new(BIO_s_mem()); BIO_read(mem, PAnsiChar(keystring), length(PAnsiChar(keystring))); try result := PEM_read_bio_PrivateKey(keybio, k, nil, nil); finally BIO_free_all(mem); end; end;
これが私の実装例の終わりです。 プロジェクトソースは
Githubで入手できます。
イトチニキ:
UPDコメントの議論から追加します:
公開鍵で必要な文字列を暗号化する場合、
秘密でのみ解読され、その逆も同様です-秘密であれば、公開鍵でのみ解読できます。 私の場合、クライアントはデータを暗号化する公開鍵を持ち、サーバー上でのみ秘密鍵で復号化できます。