Module: Sdkey::Crypto::Seal
- Defined in:
- lib/sdkey/crypto/seal.rb
Overview
Ed25519, HKDF session keys, and AES-GCM seal helpers.
Defined Under Namespace
Classes: SealedEnvelope
Class Method Summary collapse
- .derive_session_aes_key(client_nonce:, server_nonce:, salt_b64:, app_id:) ⇒ Object
- .import_public_key(public_key_b64) ⇒ Object
- .open_aes_gcm(aes_key, envelope) ⇒ Object
- .seal_aes_gcm(aes_key, plaintext) ⇒ Object
- .verify_signature(public_key, payload, signature_b64) ⇒ Object
Class Method Details
.derive_session_aes_key(client_nonce:, server_nonce:, salt_b64:, app_id:) ⇒ Object
39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/sdkey/crypto/seal.rb', line 39 def derive_session_aes_key(client_nonce:, server_nonce:, salt_b64:, app_id:) ikm = client_nonce.b + server_nonce.b salt = Encoding.base64_to_bytes(salt_b64) info = "#{Constants::SESSION_HKDF_INFO_PREFIX}#{app_id}".b OpenSSL::KDF.hkdf( ikm, salt: salt, info: info, length: Constants::SESSION_AES_KEY_BYTES, hash: "SHA256" ) end |
.import_public_key(public_key_b64) ⇒ Object
26 27 28 29 |
# File 'lib/sdkey/crypto/seal.rb', line 26 def import_public_key(public_key_b64) raw = Encoding.base64_to_bytes(public_key_b64) OpenSSL::PKey.new_raw_public_key("ED25519", raw) end |
.open_aes_gcm(aes_key, envelope) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/sdkey/crypto/seal.rb', line 67 def open_aes_gcm(aes_key, envelope) if envelope.is_a?(SealedEnvelope) iv_b64 = envelope.iv_b64 ciphertext_b64 = envelope.ciphertext_b64 tag_b64 = envelope.tag_b64 else iv_b64 = envelope["ivB64"] || envelope[:ivB64] || envelope["iv_b64"] || envelope[:iv_b64] ciphertext_b64 = envelope["ciphertextB64"] || envelope[:ciphertextB64] || envelope["ciphertext_b64"] || envelope[:ciphertext_b64] tag_b64 = envelope["tagB64"] || envelope[:tagB64] || envelope["tag_b64"] || envelope[:tag_b64] end iv = Encoding.base64_to_bytes(iv_b64) ciphertext = Encoding.base64_to_bytes(ciphertext_b64) tag = Encoding.base64_to_bytes(tag_b64) cipher = OpenSSL::Cipher.new("aes-256-gcm") cipher.decrypt cipher.key = aes_key cipher.iv = iv cipher.auth_tag = tag cipher.update(ciphertext) + cipher.final end |
.seal_aes_gcm(aes_key, plaintext) ⇒ Object
52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/sdkey/crypto/seal.rb', line 52 def seal_aes_gcm(aes_key, plaintext) iv = SecureRandom.random_bytes(Constants::AES_GCM_IV_BYTES) cipher = OpenSSL::Cipher.new("aes-256-gcm") cipher.encrypt cipher.key = aes_key cipher.iv = iv ciphertext = cipher.update(plaintext.b) + cipher.final tag = cipher.auth_tag(Constants::AES_GCM_TAG_BYTES) SealedEnvelope.new( iv_b64: Encoding.bytes_to_base64(iv), ciphertext_b64: Encoding.bytes_to_base64(ciphertext), tag_b64: Encoding.bytes_to_base64(tag) ) end |
.verify_signature(public_key, payload, signature_b64) ⇒ Object
31 32 33 34 35 36 37 |
# File 'lib/sdkey/crypto/seal.rb', line 31 def verify_signature(public_key, payload, signature_b64) signature = Encoding.base64_to_bytes(signature_b64) = CanonicalJson.canonical_json(payload) public_key.verify(nil, signature, ) rescue OpenSSL::PKey::PKeyError, OpenSSL::OpenSSLError false end |