Class: Virgil::SDK::Cryptography::VirgilCrypto

Inherits:
Object
  • Object
show all
Includes:
Crypto
Defined in:
lib/virgil/sdk/cryptography/virgil_crypto.rb

Overview

Wrapper for cryptographic operations.

Class provides a cryptographic operations in applications, such as hashing, signature generation and verification, and encryption and decryption

Defined Under Namespace

Classes: SignatureIsNotValid

Constant Summary collapse

CUSTOM_PARAM_KEY_SIGNATURE =
Crypto::Bytes.from_string(
  'VIRGIL-DATA-SIGNATURE'
)

Instance Method Summary collapse

Instance Method Details

#calculate_fingerprint(bytes) ⇒ Object

Calculates the fingerprint.

Args:

bytes: data bytes for fingerprint calculation.

Returns:

Fingerprint of the source data.


371
372
373
374
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 371

def calculate_fingerprint(bytes)
  hash_bytes = self.compute_hash(bytes, Hashes::HashAlgorithm::SHA256)
  Hashes::Fingerprint.new(hash_bytes)
end

#compute_hash(bytes, algorithm) ⇒ Object

Computes the hash of specified data.

Args:

bytes: data bytes for fingerprint calculation.
algorithm: hashing algorithm.
  The possible values can be found in HashAlgorithm enum.

Returns:

Hash bytes.


385
386
387
388
389
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 385

def compute_hash(bytes, algorithm)
  native_algorithm = Hashes::HashAlgorithm.convert_to_native(algorithm)
  native_hasher = Crypto::Native::VirgilHash.new(native_algorithm)
  wrap_bytes(native_hasher.hash(bytes))
end

#compute_public_key_hash(public_key) ⇒ Object

Computes the hash of specified public key using SHA256 algorithm.

Args:

public_key: public key for hashing.

Returns:

Hash bytes.


398
399
400
401
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 398

def compute_public_key_hash(public_key)
  public_key_der = Crypto::Native::VirgilKeyPair.public_key_to_der(public_key)
  self.compute_hash(public_key_der, Hashes::HashAlgorithm::SHA256)
end

#decrypt(cipher_bytes, private_key) ⇒ Object

Decrypts the specified bytes using Private key.

Args:

bytes: encrypted bytes bytes for decryption.
private_key: private key for decryption.

Returns:

Decrypted bytes bytes.


212
213
214
215
216
217
218
219
220
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 212

def decrypt(cipher_bytes, private_key)
  cipher = Crypto::Native::VirgilCipher.new
  decrypted_bytes = cipher.decrypt_with_key(
    cipher_bytes,
    private_key.receiver_id,
    private_key.value
  )
  wrap_bytes(decrypted_bytes)
end

#decrypt_stream(input_stream, output_stream, private_key) ⇒ Object

Decrypts the specified stream using Private key.

Args:

input_stream: readable stream containing input data.
output_stream: writable stream for output.
private_key: private key for decryption.


323
324
325
326
327
328
329
330
331
332
333
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 323

def decrypt_stream(input_stream, output_stream, private_key)
  cipher = Crypto::Native::VirgilChunkCipher.new
  source = Crypto::VirgilStreamDataSource.new(input_stream)
  sink = Crypto::VirgilStreamDataSink.new(output_stream)
  cipher.decrypt_with_key(
    source,
    sink,
    private_key.receiver_id,
    private_key.value
  )
end

#decrypt_then_verify(bytes, private_key, public_key) ⇒ Object

Decrypts and verifies the data.

Args:

bytes: encrypted data bytes.
private_key: private key for decryption.
public_key: public key for verification.

Returns:

Decrypted data bytes.

Raises:

SignatureIsNotValid: if signature is not verified.


259
260
261
262
263
264
265
266
267
268
269
270
271
272
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 259

def decrypt_then_verify(bytes, private_key, public_key)
  cipher = Crypto::Native::VirgilCipher.new
  decrypted_bytes = cipher.decrypt_with_key(
    bytes,
    private_key.receiver_id,
    private_key.value
  )
  signature = cipher.custom_params.get_data(CUSTOM_PARAM_KEY_SIGNATURE)
  is_valid = self.verify(decrypted_bytes, signature, public_key)
  unless is_valid
    raise SignatureIsNotValid.new
  end
  wrap_bytes(decrypted_bytes)
end

#encrypt(bytes, *recipients) ⇒ Object

Encrypts the specified bytes using recipients Public keys.

Args:

bytes: raw data bytes for encryption.
recipients: list of recipients' public keys.

Returns:

Encrypted bytes bytes.


196
197
198
199
200
201
202
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 196

def encrypt(bytes, *recipients)
  cipher = Crypto::Native::VirgilCipher.new
  recipients.each do |public_key|
    cipher.add_key_recipient(public_key.receiver_id, public_key.value)
  end
  wrap_bytes(cipher.encrypt(bytes))
end

#encrypt_stream(input_stream, output_stream, *recipients) ⇒ Object

Encrypts the specified stream using recipients Public keys.

Args:

input_stream: readable stream containing input bytes.
output_stream: writable stream for output.
recipients: list of recipients' public keys.


307
308
309
310
311
312
313
314
315
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 307

def encrypt_stream(input_stream, output_stream, *recipients)
  cipher = Crypto::Native::VirgilChunkCipher.new
  recipients.each do |public_key|
    cipher.add_key_recipient(public_key.receiver_id, public_key.value)
  end
  source = Crypto::VirgilStreamDataSource.new(input_stream)
  sink = Crypto::VirgilStreamDataSink.new(output_stream)
  wrap_bytes(cipher.encrypt(source, sink))
end

#export_private_key(private_key, password = nil) ⇒ Object

Exports the Private key into material representation.

Args:

private_key: private key for export.
password: private key password, nil by default.

Returns:

Key material representation bytes.


135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 135

def export_private_key(private_key, password=nil)
  unless password
    return Crypto::Native::VirgilKeyPair.private_key_to_der(
      private_key.value
    )
  end

  password_bytes = Crypto::Bytes.from_string(password)
  private_key_bytes = Crypto::Native::VirgilKeyPair.encrypt_private_key(
    private_key.value,
    password_bytes
  )
  wrap_bytes(
    Crypto::Native::VirgilKeyPair.private_key_to_der(
      private_key_bytes,
      password_bytes
    )
  )
end

#export_public_key(public_key) ⇒ Object

Exports the Public key into material representation.

Args:

public_key: public key for export.

Returns:

Key material representation bytes.


162
163
164
165
166
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 162

def export_public_key(public_key)
  wrap_bytes(
    Crypto::Native::VirgilKeyPair.public_key_to_der(public_key.value)
  )
end

#extract_public_key(private_key) ⇒ Object

Extracts the Public key from Private key.

Args:

private_key: source private key for extraction.

Returns:

Exported public key.


175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 175

def extract_public_key(private_key)
  public_key_bytes = Crypto::Native::VirgilKeyPair.extract_public_key(
    private_key.value,
    []
  )
  Keys::PublicKey.new(
    private_key.receiver_id,
    wrap_bytes(
      Crypto::Native::VirgilKeyPair.public_key_to_der(public_key_bytes)
    )
  )
end

#generate_keys(key_pair_type = Keys::KeyPairType::Default) ⇒ Object

Generates asymmetric key pair that is comprised of both public and private keys by specified type. Args:

key_pair_type: type of the generated keys.
  The possible values can be found in KeyPairType enum.

Returns:

Generated key pair.


62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 62

def generate_keys(key_pair_type=Keys::KeyPairType::Default)
  native_type = Keys::KeyPairType.convert_to_native(key_pair_type)
  native_key_pair = Crypto::Native::VirgilKeyPair.generate(native_type)
  key_pair_id = self.compute_public_key_hash(native_key_pair.public_key)
  private_key = Keys::PrivateKey.new(
    key_pair_id,
    wrap_bytes(
      Crypto::Native::VirgilKeyPair.private_key_to_der(
        native_key_pair.private_key
      )
    )
  )
  public_key = Keys::PublicKey.new(
    key_pair_id,
    wrap_bytes(
      Crypto::Native::VirgilKeyPair.public_key_to_der(
        native_key_pair.public_key
      )
    )
  )
  return Keys::KeyPair.new(private_key, public_key)
end

#import_private_key(key_bytes, password = nil) ⇒ Object

Imports the Private key from material representation.

Args:

key_bytes: key material representation bytes.
password: private key password, nil by default.

Returns:

Imported private key.


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 93

def import_private_key(key_bytes, password=nil)
  decrypted_private_key = if !password
    Crypto::Native::VirgilKeyPair.private_key_to_der(key_bytes)
  else
    Crypto::Native::VirgilKeyPair.decrypt_private_key(
      key_bytes,
      Crypto::Bytes.from_string(password)
    )
  end

  public_key_bytes = Crypto::Native::VirgilKeyPair.extract_public_key(
    decrypted_private_key, []
  )
  key_pair_id = self.compute_public_key_hash(public_key_bytes)
  private_key_bytes = Crypto::Native::VirgilKeyPair.private_key_to_der(
    decrypted_private_key
  )
  return Keys::PrivateKey.new(key_pair_id, wrap_bytes(private_key_bytes))
end

#import_public_key(key_bytes) ⇒ Object

Imports the Public key from material representation.

Args:

key_bytes: key material representation bytes.

Returns:

Imported public key.


120
121
122
123
124
125
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 120

def import_public_key(key_bytes)
  key_pair_id = self.compute_public_key_hash(key_bytes)
  public_key_bytes =
    Crypto::Native::VirgilKeyPair.public_key_to_der(key_bytes)
  Keys::PublicKey.new(key_pair_id, wrap_bytes(public_key_bytes))
end

#sign(bytes, private_key) ⇒ Object

Signs the specified data using Private key.

Args:

bytes: raw data bytes for signing.
private_key: private key for signing.

Returns:

Signature data.


282
283
284
285
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 282

def sign(bytes, private_key)
  signer = Crypto::Native::VirgilSigner.new
  wrap_bytes(signer.sign(bytes, private_key.value))
end

#sign_stream(input_stream, private_key) ⇒ Object

Signs the specified stream using Private key.

Args:

input_stream: readable stream containing input data.
private_key: private key for signing.

Returns:

Signature bytes.


343
344
345
346
347
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 343

def sign_stream(input_stream, private_key)
  signer = Crypto::Native::VirgilStreamSigner.new
  source = Crypto::VirgilStreamDataSource.new(input_stream)
  wrap_bytes(signer.sign(source, private_key.value))
end

#sign_then_encrypt(bytes, private_key, *recipients) ⇒ Object

Signs and encrypts the data.

Args:

bytes: data bytes for signing and encryption.
private_key: private key to sign the data.
recipients: list of recipients' public keys.
  Used for data encryption.

Returns:

Signed and encrypted data bytes.


232
233
234
235
236
237
238
239
240
241
242
243
244
245
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 232

def sign_then_encrypt(bytes, private_key, *recipients)
  signer = Crypto::Native::VirgilSigner.new
  signature = signer.sign(bytes, private_key.value)
  cipher = Crypto::Native::VirgilCipher.new
  custom_bytes = cipher.custom_params
  custom_bytes.set_data(
    CUSTOM_PARAM_KEY_SIGNATURE,
    signature
  )
  recipients.each do |public_key|
    cipher.add_key_recipient(public_key.receiver_id, public_key.value)
  end
  wrap_bytes(cipher.encrypt(bytes))
end

#verify(bytes, signature, signer_public_key) ⇒ Object

Verifies the specified signature using original data and signer’s public key.

Args:

bytes: original data bytes for verification.
signature: signature bytes for verification.
signer_public_key: signer public key for verification.

Returns:

True if signature is valid, False otherwise.


296
297
298
299
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 296

def verify(bytes, signature, signer_public_key)
  signer = Crypto::Native::VirgilSigner.new
  signer.verify(bytes, signature, signer_public_key.value)
end

#verify_stream(input_stream, signature, signer_public_key) ⇒ Object

Verifies the specified signature using original stream and signer’s Public key.

Args:

input_stream: readable stream containing input data.
signature: signature bytes for verification.
signer_public_key: signer public key for verification.

Returns:

True if signature is valid, False otherwise.


358
359
360
361
362
# File 'lib/virgil/sdk/cryptography/virgil_crypto.rb', line 358

def verify_stream(input_stream, signature, signer_public_key)
  signer = Crypto::Native::VirgilStreamSigner.new
  source = Crypto::VirgilStreamDataSource.new(input_stream)
  signer.verify(source, signature, signer_public_key.value)
end