ccipher_factory 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/Gemfile +30 -0
- data/Gemfile.lock-java +65 -0
- data/Gemfile.lock-ruby +67 -0
- data/README.md +80 -0
- data/Rakefile +10 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/ccipher_factory.gemspec +46 -0
- data/lib/ccipher_factory/asymkey/asymkey.rb +16 -0
- data/lib/ccipher_factory/asymkey/asymkey_generator.rb +87 -0
- data/lib/ccipher_factory/asymkey/ecc_keypair.rb +56 -0
- data/lib/ccipher_factory/asymkey_cipher/asymkey_cipher.rb +63 -0
- data/lib/ccipher_factory/asymkey_cipher/asymkey_signer.rb +44 -0
- data/lib/ccipher_factory/asymkey_cipher/ecc/ecc_att_decrypt.rb +55 -0
- data/lib/ccipher_factory/asymkey_cipher/ecc/ecc_att_encrypt.rb +70 -0
- data/lib/ccipher_factory/asymkey_cipher/ecc/ecc_att_signer.rb +88 -0
- data/lib/ccipher_factory/asymkey_cipher/ecc/ecc_att_verifier.rb +100 -0
- data/lib/ccipher_factory/asymkey_cipher/ecc/ecc_decrypt.rb +80 -0
- data/lib/ccipher_factory/asymkey_cipher/ecc/ecc_encrypt.rb +101 -0
- data/lib/ccipher_factory/asymkey_cipher/ecc/ecc_signer.rb +80 -0
- data/lib/ccipher_factory/asymkey_cipher/ecc/ecc_verifier.rb +56 -0
- data/lib/ccipher_factory/composite_cipher/composite_cipher.rb +28 -0
- data/lib/ccipher_factory/composite_cipher/decrypt_verifier.rb +116 -0
- data/lib/ccipher_factory/composite_cipher/sign_encryptor.rb +100 -0
- data/lib/ccipher_factory/compression/compression_helper.rb +103 -0
- data/lib/ccipher_factory/compression/compressor.rb +55 -0
- data/lib/ccipher_factory/compression/zlib_compressor.rb +48 -0
- data/lib/ccipher_factory/compression/zlib_decompressor.rb +67 -0
- data/lib/ccipher_factory/digest/digest.rb +180 -0
- data/lib/ccipher_factory/digest/supported_digest.rb +47 -0
- data/lib/ccipher_factory/encoding/asn1.rb +43 -0
- data/lib/ccipher_factory/encoding/bin_struct.rb +207 -0
- data/lib/ccipher_factory/encoding/binenc_constant.rb +149 -0
- data/lib/ccipher_factory/helpers/common.rb +124 -0
- data/lib/ccipher_factory/kcv/kcv.rb +89 -0
- data/lib/ccipher_factory/kdf/hkdf.rb +114 -0
- data/lib/ccipher_factory/kdf/kdf.rb +73 -0
- data/lib/ccipher_factory/kdf/pbkdf2.rb +82 -0
- data/lib/ccipher_factory/kdf/scrypt.rb +105 -0
- data/lib/ccipher_factory/shamir/shamir_sharing.rb +293 -0
- data/lib/ccipher_factory/shamir/shamir_sharing_helper.rb +88 -0
- data/lib/ccipher_factory/symkey/derived_symkey.rb +110 -0
- data/lib/ccipher_factory/symkey/hardware_symkey.rb +0 -0
- data/lib/ccipher_factory/symkey/soft_symkey.rb +63 -0
- data/lib/ccipher_factory/symkey/symkey.rb +122 -0
- data/lib/ccipher_factory/symkey/symkey_generator.rb +70 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_att_decrypt.rb +64 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_att_encrypt.rb +65 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_att_sign.rb +84 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_att_verify.rb +85 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_cipher.rb +101 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_decrypt.rb +144 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_encrypt.rb +164 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_sign.rb +70 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_signer.rb +59 -0
- data/lib/ccipher_factory/symkey_cipher/symkey_verify.rb +76 -0
- data/lib/ccipher_factory/version.rb +5 -0
- data/lib/ccipher_factory.rb +52 -0
- data/run_test.rb +27 -0
- metadata +172 -0
@@ -0,0 +1,88 @@
|
|
1
|
+
|
2
|
+
#require_relative 'shamir_sharing'
|
3
|
+
|
4
|
+
module CcipherFactory
|
5
|
+
module ShamirSharingHelper
|
6
|
+
|
7
|
+
class ShamirSharingError < StandardError; end
|
8
|
+
class InvalidShare < StandardError; end
|
9
|
+
class NotEnoughShare < StandardError; end
|
10
|
+
|
11
|
+
def shamir_split(data, totalShare, reqShare)
|
12
|
+
|
13
|
+
rand = Ccrypto::AlgoFactory.engine(Ccrypto::SecureRandomConfig)
|
14
|
+
|
15
|
+
ssc = Ccrypto::SecretSharingConfig.new
|
16
|
+
ssc.split_into = totalShare
|
17
|
+
ssc.required_parts = reqShare
|
18
|
+
ss = Ccrypto::AlgoFactory.engine(ssc)
|
19
|
+
|
20
|
+
serial = rand.random_bytes(8)
|
21
|
+
shares = ss.split(data)
|
22
|
+
shares = shares.map { |s|
|
23
|
+
ts = BinStruct.instance.struct(:shared_secret)
|
24
|
+
ts.req_share = reqShare
|
25
|
+
ts.share_id = s[0]
|
26
|
+
ts.serial = serial
|
27
|
+
ts.shared_value = s[1]
|
28
|
+
ts.encoded
|
29
|
+
}
|
30
|
+
|
31
|
+
#shares = []
|
32
|
+
#(1..totalShare).each do |i|
|
33
|
+
# share = ss.compute_share(i)
|
34
|
+
# ts = Encoding::ASN1Encoder.instance(:shared_secret)
|
35
|
+
# ts.set(:req_share, reqShare)
|
36
|
+
# ts.set(:share_id, share[0])
|
37
|
+
# ts.set(:serial, serial)
|
38
|
+
# sbin = share[1].map { |v| v.chr }.join
|
39
|
+
# ts.set(:shared_value, sbin)
|
40
|
+
# shares << ts.to_asn1
|
41
|
+
#end
|
42
|
+
|
43
|
+
shares
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
def shamir_recover(shares)
|
48
|
+
|
49
|
+
shares = [shares] if not shares.is_a?(Array)
|
50
|
+
shares = [] if is_empty?(shares)
|
51
|
+
|
52
|
+
reqShare = nil
|
53
|
+
res = { }
|
54
|
+
foundSerial = nil
|
55
|
+
shares.each do |s|
|
56
|
+
ts = BinStruct.instance.struct_from_bin(s)
|
57
|
+
|
58
|
+
raise ShamirSharingError, "Not a shared secret envelope [#{ts.id}]" if ts.oid != BTag.constant_value(:shared_secret)
|
59
|
+
|
60
|
+
serial = ts.serial
|
61
|
+
raise InvalidShare, "Given share not in same batch. Cannot proceed" if not_empty?(foundSerial) and serial != foundSerial
|
62
|
+
|
63
|
+
rs = ts.req_share
|
64
|
+
raise ShamirSharingError, "Inconsistancy required shares value in given shares" if not_empty?(reqShare) and rs != reqShare
|
65
|
+
reqShare = rs
|
66
|
+
|
67
|
+
sid = ts.share_id
|
68
|
+
if not res.keys.include?(sid)
|
69
|
+
val = ts.shared_value
|
70
|
+
#res[sid.to_i] = val.chars.map(&:ord)
|
71
|
+
res[sid.to_i] = val
|
72
|
+
end
|
73
|
+
|
74
|
+
foundSerial = serial
|
75
|
+
end
|
76
|
+
|
77
|
+
raise NotEnoughShare, "Required #{reqShare} share(s) but only #{res.size} is/are given" if res.size < reqShare or res.size == 0
|
78
|
+
|
79
|
+
#ssc = Ccrypto::SecretSharingConfig.new
|
80
|
+
#ssc.required_parts = reqShare
|
81
|
+
#ss = Ccrypto::AlgoFactory.engine(ssc)
|
82
|
+
ss = Ccrypto::AlgoFactory.engine(Ccrypto::SecretSharingConfig)
|
83
|
+
ss.combine(reqShare, res)
|
84
|
+
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
|
2
|
+
require_relative '../kdf/kdf'
|
3
|
+
|
4
|
+
module CcipherFactory
|
5
|
+
class DerivedSymKey
|
6
|
+
include TR::CondUtils
|
7
|
+
include SymKey
|
8
|
+
include Common
|
9
|
+
|
10
|
+
def self.from_encoded(bin, &block)
|
11
|
+
ts = BinStruct.instance.struct_from_bin(bin)
|
12
|
+
from_tspec(ts, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.from_tspec(ts, &block)
|
16
|
+
|
17
|
+
raise SymKeyError, "Block is required" if not block
|
18
|
+
|
19
|
+
pass = block.call(:password)
|
20
|
+
raise SymKeyError, "Password to derive symkey is not available" if is_empty?(pass)
|
21
|
+
|
22
|
+
keytype = BTag.value_constant(ts.keytype)
|
23
|
+
keysize = ts.keysize
|
24
|
+
dsk = DerivedSymKey.new(keytype, keysize)
|
25
|
+
dsk.kdf = KDF.from_encoded(ts.kdf_config)
|
26
|
+
dsk.derive(pass)
|
27
|
+
|
28
|
+
kcvBin = ts.kcv
|
29
|
+
|
30
|
+
# default is NOT to generate the KCV flag to beat the recursive test
|
31
|
+
if block
|
32
|
+
if not_empty?(kcvBin) and block.call(:pre_verify_password) == true
|
33
|
+
kcv = KCV.from_encoded(kcvBin)
|
34
|
+
kcv.key = dsk
|
35
|
+
raise SymKeyError, "Given password is incorrect" if not kcv.is_matched?
|
36
|
+
end
|
37
|
+
#else
|
38
|
+
# raise SymKeyError, "Given password is incorrect" if not kcv.is_matched?
|
39
|
+
end
|
40
|
+
|
41
|
+
dsk
|
42
|
+
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.logger
|
46
|
+
if @logger.nil?
|
47
|
+
@logger = Tlogger.new
|
48
|
+
@logger.tag = :derived_symkey
|
49
|
+
end
|
50
|
+
@logger
|
51
|
+
end
|
52
|
+
|
53
|
+
attr_accessor :kdf
|
54
|
+
def activate_password_verifier
|
55
|
+
@passVer = true
|
56
|
+
end
|
57
|
+
def deactivate_password_verifier
|
58
|
+
@passVer = false
|
59
|
+
end
|
60
|
+
|
61
|
+
def derive(pass, eng = :scrypt, &block)
|
62
|
+
|
63
|
+
if is_empty?(@kdf)
|
64
|
+
@kdf = KDF.instance(eng)
|
65
|
+
if block
|
66
|
+
case eng
|
67
|
+
when :scrypt
|
68
|
+
@kdf.cost = block.call(:kdf_scrypt_cost)
|
69
|
+
@kdf.parallel = block.call(:kdf_scrypt_parallel)
|
70
|
+
@kdf.blocksize = block.call(:kdf_scrypt_blocksize)
|
71
|
+
@kdf.salt = block.call(:kdf_scrypt_salt)
|
72
|
+
@kdf.digestAlgo = block.call(:kdf_scrypt_digestAlgo)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
@kdf.derive_init(@keysize)
|
77
|
+
end
|
78
|
+
|
79
|
+
@kdf.derive_update(pass)
|
80
|
+
@kdfAsn1 = @kdf.derive_final
|
81
|
+
|
82
|
+
@key = @kdf.derivedVal
|
83
|
+
|
84
|
+
#logger.debug "Derived : #{@key}"
|
85
|
+
|
86
|
+
end
|
87
|
+
|
88
|
+
def encoded
|
89
|
+
|
90
|
+
ts = BinStruct.instance.struct(:symkey_derived)
|
91
|
+
ts.keytype = BTag.constant_value(@keytype)
|
92
|
+
ts.keysize = @keysize
|
93
|
+
ts.kdf_config = @kdfAsn1
|
94
|
+
if @passVer == true
|
95
|
+
kcv = KCV.new
|
96
|
+
kcv.key = self
|
97
|
+
ts.kcv = kcv.encoded
|
98
|
+
else
|
99
|
+
ts.kcv = ""
|
100
|
+
end
|
101
|
+
ts.encoded
|
102
|
+
|
103
|
+
end
|
104
|
+
|
105
|
+
def logger
|
106
|
+
self.class.logger
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
File without changes
|
@@ -0,0 +1,63 @@
|
|
1
|
+
|
2
|
+
require_relative 'symkey'
|
3
|
+
|
4
|
+
module CcipherFactory
|
5
|
+
class SoftSymKey
|
6
|
+
include TR::CondUtils
|
7
|
+
include SymKey
|
8
|
+
include Common
|
9
|
+
|
10
|
+
def self.from_encoded(bin, &block)
|
11
|
+
ts = BinStruct.instance.struct_from_bin(bin)
|
12
|
+
from_tspec(ts, &block)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.from_tspec(ts, &block)
|
16
|
+
|
17
|
+
#raise SymKeyError, "Given envelope not symkey enveloppe [#{ts.id}]" if ts.id != :symkey
|
18
|
+
raise SymKeyError, "Given envelope not symkey enveloppe [#{ts.oid}]" if ts.oid != BTag.constant_value(:symkey)
|
19
|
+
|
20
|
+
#keytype = Tag.constant_key(ts.value(:keytype))
|
21
|
+
#keysize = ts.value(:keysize)
|
22
|
+
#key = ts.value(:key)
|
23
|
+
|
24
|
+
keytype = BTag.value_constant(ts.keytype)
|
25
|
+
keysize = ts.keysize
|
26
|
+
key = ts.key
|
27
|
+
if is_empty?(key)
|
28
|
+
if not block
|
29
|
+
raise SymKeyError, "Key is not in the meta data. Key is required to complete the construction of the object"
|
30
|
+
end
|
31
|
+
key = block.call(:key)
|
32
|
+
end
|
33
|
+
|
34
|
+
SoftSymKey.new(keytype, keysize, key)
|
35
|
+
end
|
36
|
+
|
37
|
+
##
|
38
|
+
# Mixin methods
|
39
|
+
##
|
40
|
+
def initialize(keytype, keysize, key = nil)
|
41
|
+
super(keytype, keysize, key)
|
42
|
+
end
|
43
|
+
|
44
|
+
def encoded
|
45
|
+
ts = BinStruct.instance.struct(:symkey)
|
46
|
+
ts.keytype = BTag.constant_value(@keytype)
|
47
|
+
ts.keysize = @keysize
|
48
|
+
if is_attach_mode?
|
49
|
+
case @key
|
50
|
+
when String
|
51
|
+
ts.key = @key
|
52
|
+
else
|
53
|
+
ts.key = @key.to_bin
|
54
|
+
end
|
55
|
+
else
|
56
|
+
ts.key = ""
|
57
|
+
end
|
58
|
+
ts.encoded
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
|
2
|
+
require_relative '../shamir/shamir_sharing_helper'
|
3
|
+
|
4
|
+
module CcipherFactory
|
5
|
+
#
|
6
|
+
# Generic category to handle 4 types of symkey:
|
7
|
+
# - software internal generated symkey (key value is generated internally)
|
8
|
+
# - software external generated symkey (key value is being set by caller)
|
9
|
+
# - derived symkey (key value is derived from password)
|
10
|
+
# - hardware symkey (key value is stored in hardware and not going to be available)
|
11
|
+
module SymKey
|
12
|
+
extend TR::CondUtils
|
13
|
+
include ShamirSharingHelper
|
14
|
+
|
15
|
+
class SymKeyError < StandardError; end
|
16
|
+
|
17
|
+
|
18
|
+
#module ClassMethods
|
19
|
+
# include ShamirSharingHelper
|
20
|
+
|
21
|
+
# def from_shares(keytype, keysize, shares)
|
22
|
+
# #self.send(:initialize, *[keytype, keysize, shamir_recover(shares)])
|
23
|
+
# #SymKey.instance_method(:initialize).bind(self).call(keytype, keysize, shamir_recover(shares))
|
24
|
+
|
25
|
+
# end
|
26
|
+
#end
|
27
|
+
#def self.included(klass)
|
28
|
+
# klass.extend(ClassMethods)
|
29
|
+
#end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Mixin methods
|
33
|
+
##
|
34
|
+
|
35
|
+
# Symmetric key type. Supported key type refers
|
36
|
+
# CcipherFactory::SymKeyGenerator#supported_symkey
|
37
|
+
attr_accessor :keytype
|
38
|
+
|
39
|
+
# Key length in bits
|
40
|
+
attr_accessor :keysize
|
41
|
+
|
42
|
+
# Raw key. It could be bytes or key object
|
43
|
+
attr_accessor :key
|
44
|
+
|
45
|
+
def initialize(keytype, keysize, key = nil)
|
46
|
+
@keytype = keytype
|
47
|
+
@keysize = keysize
|
48
|
+
@key = key
|
49
|
+
end
|
50
|
+
|
51
|
+
# split the raw key value into secret shares
|
52
|
+
def split_key(totalShare, reqShare, &block)
|
53
|
+
shamir_split(@key, totalShare, reqShare)
|
54
|
+
end
|
55
|
+
|
56
|
+
# merge the splited share values into raw key value back
|
57
|
+
def merge_key(shares)
|
58
|
+
@key = shamir_recover(shares)
|
59
|
+
end
|
60
|
+
|
61
|
+
def dispose
|
62
|
+
@key = nil
|
63
|
+
GC.start
|
64
|
+
end
|
65
|
+
|
66
|
+
def raw_key
|
67
|
+
if not @key.nil?
|
68
|
+
nativeHelper = Ccrypto::UtilFactory.instance(:native_helper)
|
69
|
+
if @key.is_a?(String) or nativeHelper.is_byte_array?(@key)
|
70
|
+
@key
|
71
|
+
elsif @key.respond_to?(:to_bin)
|
72
|
+
@key.to_bin
|
73
|
+
else
|
74
|
+
raise SymKeyError, "Not sure how to get raw_key for #{@key.inspect}"
|
75
|
+
end
|
76
|
+
#case @key
|
77
|
+
#when String, ::Java::byte[]
|
78
|
+
# @key
|
79
|
+
#else
|
80
|
+
# if @key.respond_to?(:to_bin)
|
81
|
+
# @key.to_bin
|
82
|
+
# else
|
83
|
+
# raise SymKeyError, "Not sure how to get raw_key for #{@key.inspect}"
|
84
|
+
# end
|
85
|
+
#end
|
86
|
+
else
|
87
|
+
raise SymKeyError, "Key instance is nil. Cannot get raw_key from nil instance"
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def is_equals?(key)
|
92
|
+
comp = Ccrypto::UtilFactory.instance(:comparator)
|
93
|
+
comp.is_equal?(@key, key)
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.from_encoded(bin, &block)
|
97
|
+
raise SymKeyError, "Input should not be empty" if is_empty?(bin)
|
98
|
+
|
99
|
+
ts = BinStruct.instance.struct_from_bin(bin)
|
100
|
+
case ts.oid
|
101
|
+
when BTag.constant_value(:symkey_derived)
|
102
|
+
DerivedSymKey.from_tspec(ts, &block)
|
103
|
+
when BTag.constant_value(:symkey)
|
104
|
+
SoftSymKey.from_tspec(ts, &block)
|
105
|
+
else
|
106
|
+
raise SymKeyError, "Unknown symkey envelope '#{ts.oid}'"
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
#case ts.id
|
111
|
+
#when :symkey_derived
|
112
|
+
# DerivedSymKey.from_tspec(ts, &block)
|
113
|
+
#when :symkey
|
114
|
+
# SoftSymKey.from_tspec(ts, &block)
|
115
|
+
#else
|
116
|
+
# raise SymKeyError, "Unknown symkey envelope '#{ts.id}'"
|
117
|
+
#end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
|
2
|
+
require 'openssl'
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
require_relative 'soft_symkey'
|
6
|
+
require_relative 'derived_symkey'
|
7
|
+
|
8
|
+
module CcipherFactory
|
9
|
+
module SymKeyGenerator
|
10
|
+
include TR::CondUtils
|
11
|
+
|
12
|
+
class SymKeyGeneratorError < StandardError; end
|
13
|
+
|
14
|
+
def self.supported_symkey
|
15
|
+
#{
|
16
|
+
# aes: [[128, 256], [:cbc, :cfb, :ctr, :ofb, :gcm]],
|
17
|
+
# chacha20: [[256],[:poly1305]],
|
18
|
+
# blowfish: [[128],[:ecb, :cbc, :cfb, :ofb]],
|
19
|
+
# camellia: [[128,192,256],[:ecb, :cbc, :cfb, :ofb, :ctr]],
|
20
|
+
# aria: [[128,192,256],[:ecb, :cbc, :cfb, :ofb, :ctr, :gcm]]
|
21
|
+
#}
|
22
|
+
{
|
23
|
+
aes: { keysize: [128, 192, 256], mode: [:cbc, :cfb, :ctr, :ofb, :gcm] },
|
24
|
+
chacha20: { keysize: [256], mode: [:poly1305] },
|
25
|
+
blowfish: { keysize: [128], mode: [:ecb, :cbc, :cfb, :ofb] },
|
26
|
+
camellia: { keysize: [128, 192, 256], mode: [:ecb, :cbc, :cfb, :ofb, :ctr] },
|
27
|
+
aria: { keysize: [128, 192, 256], mode: [:ecb, :cbc, :cfb, :ofb, :ctr, :gcm] }
|
28
|
+
}.freeze
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.generate(keytype, keysize, *args, &block)
|
33
|
+
raise SymKeyGeneratorError, "Unsupported symmetric key algo '#{keytype}'. Supported symmetric keys are: #{supported_symkey.keys.join(", ")}" if not supported_symkey.keys.include?(keytype)
|
34
|
+
|
35
|
+
kc = Ccrypto::KeyConfig.new
|
36
|
+
kc.algo = keytype
|
37
|
+
kc.keysize = keysize
|
38
|
+
ke = Ccrypto::AlgoFactory.engine(Ccrypto::KeyConfig)
|
39
|
+
sk = ke.generate(kc)
|
40
|
+
|
41
|
+
#SoftSymKey.new(keytype, keysize, SecureRandom.random_bytes(keysize/8))
|
42
|
+
SoftSymKey.new(keytype, keysize, sk)
|
43
|
+
end
|
44
|
+
|
45
|
+
def self.derive(keytype, keysize, *args, &block)
|
46
|
+
raise SymKeyGeneratorError, "Unsupported symmetric key algo '#{keytype}'. Supported symmetric keys are: #{supported_symkey.keys.join(", ")}" if not supported_symkey.keys.include?(keytype)
|
47
|
+
|
48
|
+
raise SymKeyGeneratorError, "Block is required" if not block
|
49
|
+
|
50
|
+
kdf = block.call(:kdf)
|
51
|
+
kdf = :scrypt if is_empty?(kdf)
|
52
|
+
|
53
|
+
pass = block.call(:password)
|
54
|
+
raise SymKeyGeneratorError, "Password is not given to derive the symkey" if is_empty?(pass)
|
55
|
+
|
56
|
+
dsk = DerivedSymKey.new(keytype, keysize)
|
57
|
+
dsk.derive(pass, kdf, &block)
|
58
|
+
dsk
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.logger
|
62
|
+
if @logger.nil?
|
63
|
+
@logger = Tlogger.new
|
64
|
+
@logger.tag = :symkey_gen
|
65
|
+
end
|
66
|
+
@logger
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module CcipherFactory
|
4
|
+
module SymKeyCipher
|
5
|
+
module SymKeyAttDecrypt
|
6
|
+
include Common
|
7
|
+
|
8
|
+
attr_accessor :key
|
9
|
+
def att_decrypt_init(*args, &block)
|
10
|
+
|
11
|
+
raise SymKeyCipherError, "Output is required for attached decryption" if not is_output_given?
|
12
|
+
|
13
|
+
@initParams = args
|
14
|
+
|
15
|
+
if block
|
16
|
+
instance_eval(&block)
|
17
|
+
att_decrypt_final
|
18
|
+
else
|
19
|
+
self
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
def att_decrypt_update(val)
|
25
|
+
if @dec.nil?
|
26
|
+
intOutputBuf.write(val)
|
27
|
+
begin
|
28
|
+
Encoding.extract_meta(intOutputBuf) do |meta, bal|
|
29
|
+
|
30
|
+
@dec = SymKeyCipher.decryptor
|
31
|
+
@dec.output(@output)
|
32
|
+
@dec.key = @key
|
33
|
+
@dec.decrypt_init(*@initParams)
|
34
|
+
@dec.decrypt_update_meta(meta)
|
35
|
+
|
36
|
+
logger.tdebug :att_dec, "Balance has data length #{bal.length}"
|
37
|
+
att_decrypt_update(bal) if bal.length > 0
|
38
|
+
|
39
|
+
disposeOutput(intOutputBuf)
|
40
|
+
|
41
|
+
end
|
42
|
+
rescue Encoding::InsufficientData => e
|
43
|
+
end
|
44
|
+
else
|
45
|
+
logger.tdebug :att_dec, "Updating cipher size #{val.length}"
|
46
|
+
@dec.decrypt_update_cipher(val)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def att_decrypt_final
|
51
|
+
@dec.decrypt_final
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
def logger
|
56
|
+
if @logger.nil?
|
57
|
+
@logger = Tlogger.new
|
58
|
+
end
|
59
|
+
@logger
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
require_relative 'symkey_cipher'
|
3
|
+
|
4
|
+
require_relative '../compression/compression_helper'
|
5
|
+
|
6
|
+
module CcipherFactory
|
7
|
+
|
8
|
+
module SymKeyCipher
|
9
|
+
module SymKeyAttEncrypt
|
10
|
+
include Common
|
11
|
+
include Compression::CompressionHelper
|
12
|
+
|
13
|
+
attr_accessor :key, :mode
|
14
|
+
def att_encrypt_init(*args, &block)
|
15
|
+
|
16
|
+
raise SymKeyCipherError, "Cipher requires output to be set" if not is_output_given?
|
17
|
+
|
18
|
+
@enc = SymKeyCipher.encryptor
|
19
|
+
@enc.compression_on if is_compression_on?
|
20
|
+
@enc.output(intOutputFile)
|
21
|
+
@enc.key = @key
|
22
|
+
@enc.mode = @mode if not_empty?(@mode)
|
23
|
+
|
24
|
+
@enc.encrypt_init(*args)
|
25
|
+
|
26
|
+
if block
|
27
|
+
instance_eval(&block)
|
28
|
+
att_encrypt_final
|
29
|
+
else
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
def att_encrypt_update(val)
|
36
|
+
raise SymKeyCipherError, "Please call att_encrypt_init() before calling update()" if @enc.nil?
|
37
|
+
|
38
|
+
@enc.encrypt_update(val)
|
39
|
+
end
|
40
|
+
|
41
|
+
def att_encrypt_final
|
42
|
+
|
43
|
+
meta = @enc.encrypt_final
|
44
|
+
|
45
|
+
write_to_output(meta)
|
46
|
+
intOutputFile.rewind
|
47
|
+
while not intOutputFile.eof?
|
48
|
+
write_to_output(intOutputFile.read)
|
49
|
+
end
|
50
|
+
|
51
|
+
intOutputFile.close!
|
52
|
+
|
53
|
+
nil
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
def method_missing(mtd, *args, &block)
|
58
|
+
if not_empty?(@enc)
|
59
|
+
@enc.send(mtd, *args, &block)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
|
2
|
+
require_relative 'symkey_signer'
|
3
|
+
|
4
|
+
require_relative '../compression/compression_helper'
|
5
|
+
|
6
|
+
module CcipherFactory
|
7
|
+
module SymKeySigner
|
8
|
+
|
9
|
+
module SymKeyAttSign
|
10
|
+
|
11
|
+
include Common
|
12
|
+
include Compression::CompressionHelper
|
13
|
+
|
14
|
+
attr_accessor :signing_key
|
15
|
+
|
16
|
+
def att_sign_init(opts = { }, &block)
|
17
|
+
|
18
|
+
@signer = SymKeySigner.signer
|
19
|
+
@signer.signing_key = @signing_key
|
20
|
+
@signer.sign_init(opts)
|
21
|
+
|
22
|
+
@totalPlain = 0
|
23
|
+
@totalCompressed = 0
|
24
|
+
|
25
|
+
if block
|
26
|
+
instance_eval(&block)
|
27
|
+
att_sign_final
|
28
|
+
else
|
29
|
+
self
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
def att_sign_update(val)
|
35
|
+
raise SymKeySignerError, "Output is required for attached sign" if not is_output_given?
|
36
|
+
|
37
|
+
@totalPlain += val.length
|
38
|
+
@signer.sign_update(val)
|
39
|
+
res = compress_data_if_active(val)
|
40
|
+
intOutputFile.write(res)
|
41
|
+
@totalCompressed += res.length
|
42
|
+
end
|
43
|
+
|
44
|
+
def att_sign_final
|
45
|
+
|
46
|
+
meta = @signer.sign_final
|
47
|
+
|
48
|
+
#ts = Encoding::ASN1Encoder.instance(:symkey_att_sign)
|
49
|
+
ts = BinStruct.instance.struct(:symkey_att_sign)
|
50
|
+
ts.symkey_signature = meta
|
51
|
+
|
52
|
+
if is_compression_on?
|
53
|
+
compRes = compressor.compress_final
|
54
|
+
ts.compression = compRes
|
55
|
+
else
|
56
|
+
ts.compression = encode_null_compressor
|
57
|
+
end
|
58
|
+
|
59
|
+
attMeta = ts.encoded
|
60
|
+
|
61
|
+
write_to_output(attMeta)
|
62
|
+
intOutputFile.rewind
|
63
|
+
while not intOutputFile.eof?
|
64
|
+
write_to_output(intOutputFile.read)
|
65
|
+
end
|
66
|
+
|
67
|
+
logger.tdebug :symkey_att_sign, "Total Plain : #{@totalPlain} / Total Compressed : #{@totalCompressed} = #{(@totalCompressed*1.0)/@totalPlain*100} %" if is_compression_on?
|
68
|
+
|
69
|
+
intOutputFile.close!
|
70
|
+
|
71
|
+
attMeta
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
def logger
|
76
|
+
if @logger.nil?
|
77
|
+
@logger = Tlogger.new
|
78
|
+
end
|
79
|
+
@logger
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|