Class: ActionPushWeb::PayloadEncryption
- Inherits:
-
Object
- Object
- ActionPushWeb::PayloadEncryption
- Defined in:
- lib/action_push_web/payload_encryption.rb
Instance Attribute Summary collapse
-
#auth_key ⇒ Object
readonly
Returns the value of attribute auth_key.
-
#message ⇒ Object
readonly
Returns the value of attribute message.
-
#p256dh_key ⇒ Object
readonly
Returns the value of attribute p256dh_key.
Instance Method Summary collapse
- #client_public_key ⇒ Object
- #client_public_key_bn ⇒ Object
- #content_encryption_key ⇒ Object
- #encrypt ⇒ Object
- #encrypted_payload ⇒ Object
- #group ⇒ Object
- #group_name ⇒ Object
- #hash ⇒ Object
-
#initialize(message:, p256dh_key:, auth_key:) ⇒ PayloadEncryption
constructor
A new instance of PayloadEncryption.
- #nonce ⇒ Object
- #prk ⇒ Object
- #salt ⇒ Object
- #server ⇒ Object
- #server_public_key_bn ⇒ Object
- #shared_secret ⇒ Object
Constructor Details
#initialize(message:, p256dh_key:, auth_key:) ⇒ PayloadEncryption
Returns a new instance of PayloadEncryption.
3 4 5 6 7 |
# File 'lib/action_push_web/payload_encryption.rb', line 3 def initialize(message:, p256dh_key:, auth_key:) @message = @p256dh_key = p256dh_key @auth_key = auth_key end |
Instance Attribute Details
#auth_key ⇒ Object (readonly)
Returns the value of attribute auth_key.
21 22 23 |
# File 'lib/action_push_web/payload_encryption.rb', line 21 def auth_key @auth_key end |
#message ⇒ Object (readonly)
Returns the value of attribute message.
21 22 23 |
# File 'lib/action_push_web/payload_encryption.rb', line 21 def @message end |
#p256dh_key ⇒ Object (readonly)
Returns the value of attribute p256dh_key.
21 22 23 |
# File 'lib/action_push_web/payload_encryption.rb', line 21 def p256dh_key @p256dh_key end |
Instance Method Details
#client_public_key ⇒ Object
44 45 46 |
# File 'lib/action_push_web/payload_encryption.rb', line 44 def client_public_key @client_public_key ||= OpenSSL::PKey::EC::Point.new(group, client_public_key_bn) end |
#client_public_key_bn ⇒ Object
40 41 42 |
# File 'lib/action_push_web/payload_encryption.rb', line 40 def client_public_key_bn @client_public_key_bn ||= OpenSSL::BN.new(Base64.urlsafe_decode64(p256dh_key), 2) end |
#content_encryption_key ⇒ Object
59 60 61 62 63 |
# File 'lib/action_push_web/payload_encryption.rb', line 59 def content_encryption_key @content_encryption_key ||= OpenSSL::KDF.hkdf( prk, salt:, info: "Content-Encoding: aes128gcm\0", hash:, length: 16 ) end |
#encrypt ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 |
# File 'lib/action_push_web/payload_encryption.rb', line 9 def encrypt serverkey16bn = [ server_public_key_bn.to_s(16) ].pack("H*") rs = encrypted_payload.bytesize raise ArgumentError, "encrypted payload is too big" if rs > 4096 aes128gcmheader = "#{salt}" + [ rs ].pack("N*") + [ serverkey16bn.bytesize ].pack("C*") + serverkey16bn aes128gcmheader + encrypted_payload end |
#encrypted_payload ⇒ Object
71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/action_push_web/payload_encryption.rb', line 71 def encrypted_payload @encrypted_payload ||= begin cipher = OpenSSL::Cipher.new("aes-128-gcm") cipher.encrypt cipher.key = content_encryption_key cipher.iv = nonce text = cipher.update() padding = cipher.update("\2\0") e_text = text + padding + cipher.final e_tag = cipher.auth_tag e_text + e_tag end end |
#group ⇒ Object
36 37 38 |
# File 'lib/action_push_web/payload_encryption.rb', line 36 def group @group ||= OpenSSL::PKey::EC::Group.new(group_name) end |
#group_name ⇒ Object
23 |
# File 'lib/action_push_web/payload_encryption.rb', line 23 def group_name = "prime256v1" |
#hash ⇒ Object
24 |
# File 'lib/action_push_web/payload_encryption.rb', line 24 def hash = "SHA256" |
#nonce ⇒ Object
65 66 67 68 69 |
# File 'lib/action_push_web/payload_encryption.rb', line 65 def nonce @nonce ||= OpenSSL::KDF.hkdf( prk, salt:, info: "Content-Encoding: nonce\0", hash:, length: 12 ) end |
#prk ⇒ Object
52 53 54 55 56 57 |
# File 'lib/action_push_web/payload_encryption.rb', line 52 def prk @prk ||= OpenSSL::KDF.hkdf(shared_secret, salt: Base64.urlsafe_decode64(auth_key), info: "WebPush: info\0" + client_public_key_bn.to_s(2) + server_public_key_bn.to_s(2), hash:, length: 32) end |
#salt ⇒ Object
26 27 28 |
# File 'lib/action_push_web/payload_encryption.rb', line 26 def salt @salt ||= Random.new.bytes(16) end |
#server ⇒ Object
30 31 32 |
# File 'lib/action_push_web/payload_encryption.rb', line 30 def server @server ||= OpenSSL::PKey::EC.generate(group_name) end |
#server_public_key_bn ⇒ Object
34 |
# File 'lib/action_push_web/payload_encryption.rb', line 34 def server_public_key_bn = server.public_key.to_bn |
#shared_secret ⇒ Object
48 49 50 |
# File 'lib/action_push_web/payload_encryption.rb', line 48 def shared_secret @shared_secret ||= server.dh_compute_key(client_public_key) end |