Class: PqcRails::Cipher
- Inherits:
-
Object
- Object
- PqcRails::Cipher
- Defined in:
- lib/pqc_rails/cipher.rb
Overview
ActiveRecord::Encryption::Cipher互換のインターフェースを持つ独立したクラス。 ActiveRecord::Encryption.configure(cipher: PqcRails::Cipher.new, key_provider: ...)で デフォルトのAES-256-GCM単体実装を完全に置き換える。
ActiveRecord::Encryptionのkey:は「鍵そのもの」をそのまま渡してくる設計
(KeyProvider#encryption_key.secretの値がそのまま渡る)。本実装ではKeyProvider側で
key.secretがPqcRails::HybridKem::Keypair(公開鍵・秘密鍵のペア)を返すように
揃えてあるので、ここではそのKeypairを直接受け取れる。
内部的にはPhase 2と同じKEM-DEM構成(HybridKem+EnvelopeCipher)。
Session::Encryptorを再利用しないのは、ARはCipher層に外からkey:を渡す設計のため
鍵の持ち方が異なるから(Session::Encryptorは自分でKeypairを保持する)。
Constant Summary collapse
- DEFAULT_PQ_ALG_NAME =
PqcRails::Session::Encryptor::DEFAULT_PQ_ALG_NAME
Instance Method Summary collapse
- #decrypt(encrypted_message, key:) ⇒ Object
- #encrypt(clear_text, key:, deterministic: false) ⇒ Object
-
#initialize(pq_alg_name: DEFAULT_PQ_ALG_NAME) ⇒ Cipher
constructor
A new instance of Cipher.
- #iv_length ⇒ Object
- #key_length ⇒ Object
Constructor Details
#initialize(pq_alg_name: DEFAULT_PQ_ALG_NAME) ⇒ Cipher
24 25 26 |
# File 'lib/pqc_rails/cipher.rb', line 24 def initialize(pq_alg_name: DEFAULT_PQ_ALG_NAME) @pq_alg_name = pq_alg_name end |
Instance Method Details
#decrypt(encrypted_message, key:) ⇒ Object
41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/pqc_rails/cipher.rb', line 41 def decrypt(, key:) keypairs = key.is_a?(::Array) ? key : [key] last_error = nil HybridKem.open(@pq_alg_name) do |hybrid| keypairs.each do |keypair| return decrypt_with(hybrid, , keypair) rescue OpenSSL::Cipher::CipherError, PqcRails::Error, ArgumentError, TypeError => e last_error = e end end raise ::ActiveRecord::Encryption::Errors::Decryption, last_error&. end |
#encrypt(clear_text, key:, deterministic: false) ⇒ Object
28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/pqc_rails/cipher.rb', line 28 def encrypt(clear_text, key:, deterministic: false) raise ArgumentError, "PqcRails::Cipher does not support deterministic encryption" if deterministic HybridKem.open(@pq_alg_name) do |hybrid| encap = hybrid.encapsulate(key.public_key) envelope = EnvelopeCipher.new(encap.shared_secret).encrypt(clear_text) ::ActiveRecord::Encryption::Message.new(payload: envelope).tap do || .headers[:kem_ct] = encap.ciphertext end end end |
#iv_length ⇒ Object
60 61 62 |
# File 'lib/pqc_rails/cipher.rb', line 60 def iv_length EnvelopeCipher::IV_LENGTH end |
#key_length ⇒ Object
56 57 58 |
# File 'lib/pqc_rails/cipher.rb', line 56 def key_length EnvelopeCipher::KEY_LENGTH end |