Class: Virgil::SDK::HighLevel::VirgilKey

Inherits:
Object
  • Object
show all
Defined in:
lib/virgil/sdk/high_level/virgil_key.rb

Overview

This class represents a user's high-level Private key which provides a list of methods that allows to store the key and perform cryptographic operations like Decrypt, Sign etc.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(context, private_key) ⇒ VirgilKey

Initializes a new instance of the Virgil::SDK::HighLevel::VirgilKey class.



52
53
54
55
# File 'lib/virgil/sdk/high_level/virgil_key.rb', line 52

def initialize(context, private_key)
  @context = context
  @private_key = private_key
end

Instance Attribute Details

#contextVirgilContext (readonly)

manages the VirgilApi dependencies during run time.

Returns:



45
46
47
# File 'lib/virgil/sdk/high_level/virgil_key.rb', line 45

def context
  @context
end

#private_keyCryptography::Keys::PrivateKey (readonly)

private key



49
50
51
# File 'lib/virgil/sdk/high_level/virgil_key.rb', line 49

def private_key
  @private_key
end

Instance Method Details

#decrypt(cipher_buffer) ⇒ VirgilBuffer

Decrypts the specified cipher data using Virgil key.

Examples:

virgil = VirgilApi.new
# load a Virgil Key from device storage
alice_key = virgil.keys.load("[KEY_NAME]", "[OPTIONAL_KEY_PASSWORD]")

# decrypt a buffer using loaded Virgil Key
original_file_buf = alice_key.decrypt(cipher_file_buf)

Parameters:

  • cipher_buffer (VirgilBuffer, String, Crypto::Bytes)

    The encrypted data wrapped by VirgilBuffer or encrypted data in base64-encoded String or Array of bytes of encrypted data

Returns:

  • (VirgilBuffer)

    A byte array containing the result from performing the action wrapped by VirgilBuffer.

Raises:

  • (ArgumentError)

    if buffer doesn't have type VirgilBuffer, base64-encoded String or Array of bytes

See Also:



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/virgil/sdk/high_level/virgil_key.rb', line 73

def decrypt(cipher_buffer)

  buffer_to_decrypt = case cipher_buffer.class.name.split("::").last
                        when 'VirgilBuffer'
                          cipher_buffer
                        when 'String'
                          VirgilBuffer.from_base64(cipher_buffer)
                        when 'Array'
                          VirgilBuffer.from_bytes(cipher_buffer)
                        else
                          raise ArgumentError.new("Buffer has unsupported type")
                      end

  bytes = context.crypto.decrypt(buffer_to_decrypt.bytes, private_key)
  VirgilBuffer.new(bytes)
end

#decrypt_then_verify(cipher_buffer, *cards) ⇒ VirgilBuffer

Decrypts and verifies the data.

Examples:

virgil = VirgilApi.new(access_token: "[YOUR_ACCESS_TOKEN_HERE]")
# load a Virgil Key from device storage
bob_key = virgil.keys.load("[KEY_NAME]", "[OPTIONAL_KEY_PASSWORD]")

# get a sender's Virgil Card
alice_card = virgil.cards.get("[ALICE_CARD_ID]")

# decrypt the message
original_message = bob_key.decrypt_then_verify(ciphertext, alice_card).to_s

Parameters:

  • cipher_buffer (VirgilBuffer, String, Crypto::Bytes)

    The data to be decrypted and verified: The encrypted data wrapped by VirgilBuffer or encrypted data in base64-encoded String or Array of bytes of encrypted data

  • *cards (Array<VirgilCard>)

    The list of trusted Virgil Cards, which can contains the signer's VirgilCard

Returns:

  • (VirgilBuffer)

    The decrypted data, which is the original plain text before encryption the decrypted data, wrapped by VirgilBuffer

Raises:

  • (ArgumentError)

    if buffer doesn't have type VirgilBuffer, String or Array of bytes

  • (ArgumentError)

    if recipients doesn't have type Array or empty



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'lib/virgil/sdk/high_level/virgil_key.rb', line 185

def decrypt_then_verify(cipher_buffer, *cards)

  raise ArgumentError.new("card is not valid") unless cards.all? { |el| el.is_a? VirgilCard }

  buffer_to_decrypt = case cipher_buffer.class.name.split("::").last
                        when 'VirgilBuffer'
                          cipher_buffer
                        when 'String'
                          VirgilBuffer.from_base64(cipher_buffer)
                        when 'Array'
                          VirgilBuffer.from_bytes(cipher_buffer)
                        else
                          raise ArgumentError.new("Buffer has unsupported type")
                      end

  public_keys = cards.map(&:public_key)
  bytes = context.crypto.decrypt_then_verify(buffer_to_decrypt.bytes, private_key, *public_keys)
  VirgilBuffer.new(bytes)
end

#export(password = nil) ⇒ VirgilBuffer

Exports the VirgilKey to default format, specified in Crypto API.

Examples:

Export the Virgil Key to Base64 encoded string.

virgil = VirgilApi.new
# generate a new Virgil Key
alice_key = virgil.keys.generate

# export the Virgil Key to Base64 encoded string
BASE64_ENCODED_VIRGIL_KEY = alice_key.export("[OPTIONAL_KEY_PASSWORD]”).to_base64

Returns:

  • (VirgilBuffer)

    Private Key material representation bytes wrapped by VirgilBuffer

See Also:



240
241
242
# File 'lib/virgil/sdk/high_level/virgil_key.rb', line 240

def export(password=nil)
  VirgilBuffer.from_bytes(context.crypto.export_private_key(private_key, password))
end

#export_public_keyVirgilBuffer

Exports the Public key value from current VirgilKey.

Returns:

  • (VirgilBuffer)

    A new VirgilBuffer that contains Public Key value.



247
248
249
250
# File 'lib/virgil/sdk/high_level/virgil_key.rb', line 247

def export_public_key
  public_key = context.crypto.extract_public_key(private_key)
  VirgilBuffer.from_bytes(context.crypto.export_public_key(public_key))
end

#save(key_name, key_password = nil) ⇒ VirgilKey

Saves a current VirgilKey in secure storage.

Examples:

virgil = VirgilApi.new
alice_key = virgil.keys.generate.save("[KEY_NAME]", "[OPTIONAL_KEY_PASSWORD]")

Parameters:

  • key_name (String)

    The name of the key.

  • key_password (String) (defaults to: nil)

    The key password.

Returns:

Raises:

  • (KeyEntryAlreadyExistsException)

    if key storage already has item with such name

  • (ArgumentError)

    key_name is not valid if key_name is nil

  • (KeyStorageException)

    if destination folder doesn't exist or you don't have permission to write there

See Also:



217
218
219
220
221
222
223
224
225
226
# File 'lib/virgil/sdk/high_level/virgil_key.rb', line 217

def save(key_name, key_password=nil)

  raise ArgumentError.new("key_name is not valid") if key_name.nil?

  exported_private_key = context.crypto.export_private_key(private_key, key_password)
  storage_item = Cryptography::Keys::StorageItem.new(key_name, exported_private_key)
  context.key_storage.store(storage_item)
  self

end

#sign(buffer) ⇒ VirgilBuffer

Generates a digital signature for specified data using current Virgil key.

Examples:

virgil = VirgilApi.new
# load Alice's Key from protected storage
alice_key = virgil.keys.load("[KEY_NAME]", "[KEY_PASSWORD]")

message = "Hi Bob, hope you are doing well."

# generate signature of message using alice's key pair
signature = alice_key.sign(message)

Parameters:

  • buffer (VirgilBuffer, String, Crypto::Bytes)

    The data for which the digital signature will be generated. buffer can be VirgilBuffer, utf8-encoded String or Array of bytes

Returns:

  • (VirgilBuffer)

    A new buffer that containing the result from performing the action.

Raises:

  • (ArgumentError)

    if buffer doesn't have type VirgilBuffer, String or Array of bytes

See Also:



107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/virgil/sdk/high_level/virgil_key.rb', line 107

def sign(buffer)
  buffer_to_sign = case buffer.class.name.split("::").last
                     when 'VirgilBuffer'
                       buffer
                     when 'String'
                       VirgilBuffer.from_string(buffer)
                     when 'Array'
                       VirgilBuffer.from_bytes(buffer)
                     else
                       raise ArgumentError.new("Buffer has unsupported type")
                   end

  VirgilBuffer.new(context.crypto.sign(buffer_to_sign.bytes, private_key).to_s.bytes)
end

#sign_then_encrypt(buffer, recipients) ⇒ VirgilBuffer

Encrypts and signs the data.

Examples:

Alice signs the message and encrypt it for Bob

virgil = VirgilApi.new(access_token: "[YOUR_ACCESS_TOKEN_HERE]")
# load a Virgil Key from device storage
alice_key = virgil.keys.load("[KEY_NAME]", "[OPTIONAL_KEY_PASSWORD]")

# search for Virgil Cards
bob_cards = await virgil.cards.find("bob")

# prepare the message
message = "Hey Bob, how's it going?"

# sign then encrypt the message
ciphertext = alice_key.sign_then_encrypt(message, bob_cards).to_base64

Parameters:

  • buffer (VirgilBuffer, String, Crypto::Bytes)

    The data wrapped by VirgilBuffer to be encrypted and signed buffer can be VirgilBuffer, utf8-encoded String or Array of bytes

  • recipients (Array<VirgilCard>)

    The list of VirgilCard recipients.

Returns:

  • (VirgilBuffer)

    A new buffer that containing the encrypted and signed data

Raises:

  • (ArgumentError)

    if buffer doesn't have type VirgilBuffer, String or Array of bytes

  • (ArgumentError)

    if recipients doesn't have type Array or empty

See Also:



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/virgil/sdk/high_level/virgil_key.rb', line 145

def sign_then_encrypt(buffer, recipients)

  raise ArgumentError.new("recipients is not valid") if (!recipients.is_a?(Array) || recipients.empty?)
  buffer_to_sign = case buffer.class.name.split("::").last
                     when 'VirgilBuffer'
                       buffer
                     when 'String'
                       VirgilBuffer.from_string(buffer)
                     when 'Array'
                       VirgilBuffer.from_bytes(buffer)
                     else
                       raise ArgumentError.new("Buffer has unsupported type")
                   end
  public_keys = recipients.map(&:public_key)
  bytes = context.crypto.sign_then_encrypt(buffer_to_sign.bytes, private_key, *public_keys).to_s.bytes
  VirgilBuffer.new(bytes)

end