ccrypto-java 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.java-version +1 -0
- data/.rspec +3 -0
- data/Gemfile +13 -0
- data/Gemfile.lock +94 -0
- data/README.md +150 -0
- data/Rakefile +10 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/ccrypto-java.gemspec +44 -0
- data/jars/bcmail-jdk15on-165.jar +0 -0
- data/jars/bcpg-jdk15on-165.jar +0 -0
- data/jars/bcpkix-jdk15on-165.jar +0 -0
- data/jars/bcprov-ext-jdk15on-165.jar +0 -0
- data/jars/bcprov-jdk15on-165.jar +0 -0
- data/jars/bctls-jdk15on-165.jar +0 -0
- data/jars/shamir-0.6.1-p.jar +0 -0
- data/lib/ccrypto/java/data_conversion.rb +80 -0
- data/lib/ccrypto/java/engines/asn1_engine.rb +161 -0
- data/lib/ccrypto/java/engines/asn1_object.rb +12 -0
- data/lib/ccrypto/java/engines/cipher_engine.rb +255 -0
- data/lib/ccrypto/java/engines/compression_engine.rb +92 -0
- data/lib/ccrypto/java/engines/data_conversion_engine.rb +9 -0
- data/lib/ccrypto/java/engines/decompression_engine.rb +48 -0
- data/lib/ccrypto/java/engines/digest_engine.rb +208 -0
- data/lib/ccrypto/java/engines/ecc_engine.rb +263 -0
- data/lib/ccrypto/java/engines/hkdf_engine.rb +72 -0
- data/lib/ccrypto/java/engines/hmac_engine.rb +75 -0
- data/lib/ccrypto/java/engines/pbkdf2_engine.rb +87 -0
- data/lib/ccrypto/java/engines/pkcs7_engine.rb +558 -0
- data/lib/ccrypto/java/engines/rsa_engine.rb +572 -0
- data/lib/ccrypto/java/engines/scrypt_engine.rb +35 -0
- data/lib/ccrypto/java/engines/secret_key_engine.rb +44 -0
- data/lib/ccrypto/java/engines/secret_sharing_engine.rb +59 -0
- data/lib/ccrypto/java/engines/secure_random_engine.rb +76 -0
- data/lib/ccrypto/java/engines/x509_engine.rb +311 -0
- data/lib/ccrypto/java/ext/secret_key.rb +75 -0
- data/lib/ccrypto/java/ext/x509_cert.rb +48 -0
- data/lib/ccrypto/java/jce_provider.rb +52 -0
- data/lib/ccrypto/java/keybundle_store/pkcs12.rb +125 -0
- data/lib/ccrypto/java/utils/comparator.rb +20 -0
- data/lib/ccrypto/java/utils/memory_buffer.rb +77 -0
- data/lib/ccrypto/java/utils/native_helper.rb +19 -0
- data/lib/ccrypto/java/version.rb +7 -0
- data/lib/ccrypto/java.rb +30 -0
- data/lib/ccrypto/provider.rb +132 -0
- metadata +144 -0
@@ -0,0 +1,255 @@
|
|
1
|
+
|
2
|
+
require_relative '../data_conversion'
|
3
|
+
|
4
|
+
module Ccrypto
|
5
|
+
module Java
|
6
|
+
class CipherEngine
|
7
|
+
include TR::CondUtils
|
8
|
+
include DataConversion
|
9
|
+
|
10
|
+
include TeLogger::TeLogHelper
|
11
|
+
|
12
|
+
teLogger_tag :j_cipher
|
13
|
+
|
14
|
+
def self.supported_ciphers
|
15
|
+
res = java.security.Security.getAlgorithms("Cipher").to_a.delete_if { |e| e.include?(".") }.sort
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.is_supported_cipher?(c)
|
19
|
+
case c
|
20
|
+
when String, java.lang.String
|
21
|
+
javax.crypto.Cipher.getInstance(c)
|
22
|
+
when Hash
|
23
|
+
spec = to_spec(c)
|
24
|
+
javax.crypto.Cipher.getInstance(spec)
|
25
|
+
else
|
26
|
+
raise CipherEngineException, "Unsupported input #{c} to check supported cipher"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.to_spec(hash)
|
31
|
+
res = []
|
32
|
+
res << hash[:algo].to_s
|
33
|
+
res << hash[:mode].to_s
|
34
|
+
res << hash[:padding].to_s
|
35
|
+
res.join("/")
|
36
|
+
end
|
37
|
+
|
38
|
+
def supported_ciphers
|
39
|
+
self.class.supported_ciphers
|
40
|
+
end
|
41
|
+
|
42
|
+
def initialize(*args, &block)
|
43
|
+
|
44
|
+
@spec = args.first
|
45
|
+
|
46
|
+
case @spec
|
47
|
+
when String, java.lang.String, Hash
|
48
|
+
@spec = Ccrypto::DirectCipherConfig.new(@spec)
|
49
|
+
when Ccrypto::CipherConfig
|
50
|
+
else
|
51
|
+
raise Ccrypto::CipherEngineException, "Unsupported config type #{@spec.class}"
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
if block
|
56
|
+
@cipherJceProvider = block.call(:cipher_jceProvider)
|
57
|
+
@keygenJceProvider = block.call(:keygen_jceProvider)
|
58
|
+
end
|
59
|
+
|
60
|
+
cSpec = to_cipher_spec(@spec)
|
61
|
+
if @cipherJceProvider.nil?
|
62
|
+
begin
|
63
|
+
teLogger.debug "Cipher instance #{cSpec} with null provider"
|
64
|
+
@cipher = javax.crypto.Cipher.getInstance(cSpec)
|
65
|
+
rescue Exception => ex
|
66
|
+
teLogger.debug "Error #{ex.message} for spec '#{cSpec}' using null provider. Retest with BC provider"
|
67
|
+
@cipher = javax.crypto.Cipher.getInstance(cSpec, Ccrypto::Java::JCEProvider::BCProv.name)
|
68
|
+
end
|
69
|
+
else
|
70
|
+
teLogger.debug "Cipher instance #{cSpec} with provider '#{@cipherJceProvider.is_a?(String) ? @cipherJceProvider : @cipherJceProvider.name}'"
|
71
|
+
@cipher = javax.crypto.Cipher.getInstance(cSpec, @cipherJceProvider)
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
if @spec.has_key?
|
76
|
+
teLogger.debug "Using given cipher key"
|
77
|
+
|
78
|
+
else
|
79
|
+
|
80
|
+
teLogger.debug "Generating cipher key"
|
81
|
+
if @keygenJceProvider.nil?
|
82
|
+
kg = javax.crypto.KeyGenerator.getInstance(to_algo(@spec.algo))
|
83
|
+
else
|
84
|
+
kg = javax.crypto.KeyGenerator.getInstance(to_algo(@spec.algo), @keygenJceProvider)
|
85
|
+
end
|
86
|
+
|
87
|
+
kg.init(@spec.keysize.to_i)
|
88
|
+
@spec.key = kg.generateKey
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
if @spec.iv.is_a?(String)
|
93
|
+
@spec.iv = to_java_bytes(@spec.iv)
|
94
|
+
end
|
95
|
+
|
96
|
+
if @spec.is_mode?(:gcm) or @spec.is_algo?(:chacha20)
|
97
|
+
if is_empty?(@spec.iv)
|
98
|
+
teLogger.debug "Generating 12 bytes of IV"
|
99
|
+
@spec.iv = Ccrypto::Java::SecureRandomEngine.random_bytes(12)
|
100
|
+
else
|
101
|
+
teLogger.debug "Using given IV"
|
102
|
+
end
|
103
|
+
|
104
|
+
if @spec.is_mode?(:gcm)
|
105
|
+
ivParam = javax.crypto.spec.GCMParameterSpec.new(@spec.iv.length*8, @spec.iv) # 16 bytes
|
106
|
+
else
|
107
|
+
ivParam = javax.crypto.spec.IvParameterSpec.new(@spec.iv) # 16 bytes
|
108
|
+
end
|
109
|
+
|
110
|
+
elsif @spec.is_algo?(:blowfish)
|
111
|
+
if is_empty?(@spec.iv)
|
112
|
+
teLogger.debug "Generating 8 bytes of IV"
|
113
|
+
@spec.iv = Ccrypto::Java::SecureRandomEngine.random_bytes(8)
|
114
|
+
else
|
115
|
+
teLogger.debug "Using given IV"
|
116
|
+
end
|
117
|
+
ivParam = javax.crypto.spec.IvParameterSpec.new(@spec.iv)
|
118
|
+
|
119
|
+
elsif @spec.is_mode?(:cbc) or @spec.is_mode?(:ctr) or @spec.is_mode?(:cfb) or @spec.is_mode?(:ofb)
|
120
|
+
if is_empty?(@spec.iv)
|
121
|
+
teLogger.debug "Generating 16 bytes of IV"
|
122
|
+
@spec.iv = Ccrypto::Java::SecureRandomEngine.random_bytes(16)
|
123
|
+
else
|
124
|
+
teLogger.debug "Using given IV"
|
125
|
+
end
|
126
|
+
ivParam = javax.crypto.spec.IvParameterSpec.new(@spec.iv)
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
#teLogger.debug "IV : #{@spec.iv}"
|
131
|
+
|
132
|
+
case @spec.key
|
133
|
+
when Ccrypto::SecretKey
|
134
|
+
skey = @spec.key.key
|
135
|
+
when ::Java::byte[]
|
136
|
+
skey = javax.crypto.spec.SecretKeySpec.new(@spec.key, @spec.algo.to_s)
|
137
|
+
when String
|
138
|
+
skey = javax.crypto.spec.SecretKeySpec.new(to_java_bytes(@spec.key), @spec.algo.to_s)
|
139
|
+
when javax.crypto.spec.SecretKeySpec
|
140
|
+
skey = @spec.key
|
141
|
+
else
|
142
|
+
raise CipherEngineException, "Unknown key type '#{@spec.key}'"
|
143
|
+
end
|
144
|
+
|
145
|
+
#teLogger.debug "SKey : #{skey.encoded}"
|
146
|
+
|
147
|
+
case @spec.cipherOps
|
148
|
+
when :encrypt, :enc
|
149
|
+
if ivParam.nil?
|
150
|
+
teLogger.debug "Encryption mode"
|
151
|
+
@cipher.init(javax.crypto.Cipher::ENCRYPT_MODE, skey)
|
152
|
+
else
|
153
|
+
teLogger.debug "Encryption mode with IV"
|
154
|
+
@cipher.init(javax.crypto.Cipher::ENCRYPT_MODE, skey, ivParam)
|
155
|
+
end
|
156
|
+
|
157
|
+
when :decrypt, :dec
|
158
|
+
if ivParam.nil?
|
159
|
+
teLogger.debug "Decryption mode"
|
160
|
+
@cipher.init(javax.crypto.Cipher::DECRYPT_MODE, skey)
|
161
|
+
else
|
162
|
+
teLogger.debug "Decryption mode with IV"
|
163
|
+
@cipher.init(javax.crypto.Cipher::DECRYPT_MODE, skey, ivParam)
|
164
|
+
end
|
165
|
+
|
166
|
+
else
|
167
|
+
raise Ccrypto::CipherEngineException, "Cipher operation must be given"
|
168
|
+
end
|
169
|
+
|
170
|
+
if @spec.is_mode?(:gcm) and not_empty?(@spec.auth_data)
|
171
|
+
teLogger.debug "Adding additional authenticated data for GCM mode"
|
172
|
+
@cipher.updateAAD(to_java_bytes(@spec.auth_data))
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
|
177
|
+
def update(val)
|
178
|
+
teLogger.debug "Passing #{val.length} bytes to cipher"
|
179
|
+
res = @cipher.update(to_java_bytes(val))
|
180
|
+
if res.nil?
|
181
|
+
teLogger.debug "Cipher update returns nothing"
|
182
|
+
else
|
183
|
+
teLogger.debug "Cipher update output length #{res.length}"
|
184
|
+
end
|
185
|
+
res
|
186
|
+
end
|
187
|
+
|
188
|
+
def final(val = nil, &block)
|
189
|
+
baos = java.io.ByteArrayOutputStream.new
|
190
|
+
if not_empty?(val)
|
191
|
+
res = update(val)
|
192
|
+
baos.write(res) if not_empty?(res)
|
193
|
+
end
|
194
|
+
|
195
|
+
begin
|
196
|
+
res = @cipher.doFinal
|
197
|
+
|
198
|
+
teLogger.debug "Final output length : #{res.length}"
|
199
|
+
|
200
|
+
if @spec.is_mode?(:gcm) and @spec.is_encrypt_cipher_mode?
|
201
|
+
# extract auth_tag
|
202
|
+
@spec.auth_tag = res[-16..-1]
|
203
|
+
@spec.auth_tag = String.from_java_bytes(@spec.auth_tag) if not_empty?(@spec.auth_tag)
|
204
|
+
end
|
205
|
+
|
206
|
+
baos.write(res) if not_empty?(res)
|
207
|
+
baos.toByteArray
|
208
|
+
|
209
|
+
rescue Exception => ex
|
210
|
+
raise Ccrypto::CipherEngineException, ex
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def reset
|
215
|
+
#@cipher.reset
|
216
|
+
end
|
217
|
+
|
218
|
+
private
|
219
|
+
def to_algo(algo)
|
220
|
+
algo.to_s.gsub("_","-")
|
221
|
+
end
|
222
|
+
|
223
|
+
def to_cipher_spec(spec)
|
224
|
+
res = []
|
225
|
+
|
226
|
+
res << spec.algo.to_s.gsub("_","-")
|
227
|
+
|
228
|
+
res << spec.mode if not_empty?(spec.mode)
|
229
|
+
|
230
|
+
if spec.algo.to_s.downcase == "aria" and spec.mode.to_s.downcase == "gcm"
|
231
|
+
# for some reasons only aria gcm trigger this error
|
232
|
+
res << "NoPadding"
|
233
|
+
elsif spec.mode.to_s.downcase != "poly1305"
|
234
|
+
case spec.padding
|
235
|
+
when :pkcs5
|
236
|
+
res << "PKCS5Padding"
|
237
|
+
when :pkcs7
|
238
|
+
res << "PKCS7Padding"
|
239
|
+
when :nopadding
|
240
|
+
res << "NOPadding"
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
if spec.is_algo?(:chacha20)
|
245
|
+
res.join("-")
|
246
|
+
elsif spec.is_algo?(:blowfish)
|
247
|
+
res[0]
|
248
|
+
else
|
249
|
+
res.join("/")
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
|
2
|
+
require_relative '../data_conversion'
|
3
|
+
|
4
|
+
module Ccrypto
|
5
|
+
module Java
|
6
|
+
class Compression
|
7
|
+
include DataConversion
|
8
|
+
include TR::CondUtils
|
9
|
+
|
10
|
+
include TeLogger::TeLogHelper
|
11
|
+
|
12
|
+
teLogger_tag :j_compression
|
13
|
+
|
14
|
+
def initialize(*args, &block)
|
15
|
+
|
16
|
+
@config = args.first
|
17
|
+
raise CompressionError, "Compress Config is expected. Given #{@config}" if not @config.is_a?(Ccrypto::CompressionConfig)
|
18
|
+
|
19
|
+
#if block
|
20
|
+
|
21
|
+
# outPath = block.call(:out_path)
|
22
|
+
# if is_empty?(outPath)
|
23
|
+
# outFile = block.call(:out_file)
|
24
|
+
# raise CompressionError, "OutputStream required" if not outFile.is_a?(java.io.OutputStream)
|
25
|
+
# @out = outFile
|
26
|
+
# else
|
27
|
+
# @out = java.io.RandomAccessFile.new(java.io.File.new(outPath), "w")
|
28
|
+
# end
|
29
|
+
|
30
|
+
# @intBufSize = block.call(:int_buf_size) || 102400
|
31
|
+
|
32
|
+
#else
|
33
|
+
# @intBufSize = 102400
|
34
|
+
|
35
|
+
#end
|
36
|
+
|
37
|
+
#@in = java.io.RandomAccessFile.new(java.nio.file.Files.createTempFile(nil,".zl").toFile, "rw")
|
38
|
+
#@inPtr = 0
|
39
|
+
|
40
|
+
case @config.level
|
41
|
+
when :best_compression
|
42
|
+
teLogger.debug "Compression with best compression"
|
43
|
+
@eng = java.util.zip.Deflater.new(java.util.zip.Deflater::BEST_COMPRESSION)
|
44
|
+
when :best_speed
|
45
|
+
teLogger.debug "Compression with best speed"
|
46
|
+
@eng = java.util.zip.Deflater.new(java.util.zip.Deflater::BEST_SPEED)
|
47
|
+
when :no_compression
|
48
|
+
teLogger.debug "No compression"
|
49
|
+
@eng = java.util.zip.Deflater.new(java.util.zip.Deflater::NO_COMPRESSION)
|
50
|
+
else
|
51
|
+
teLogger.debug "Default compression"
|
52
|
+
@eng = java.util.zip.Deflater.new(java.util.zip.Deflater::DEFAULT_COMPRESSION)
|
53
|
+
end
|
54
|
+
|
55
|
+
teLogger.debug "Default strategy"
|
56
|
+
@eng.setStrategy(java.util.zip.Deflater::DEFAULT_STRATEGY)
|
57
|
+
|
58
|
+
@os = java.io.ByteArrayOutputStream.new
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
# returns compressed output length
|
63
|
+
def update(val)
|
64
|
+
if val.length > 0
|
65
|
+
teLogger.debug "Given #{val.length} bytes for compression"
|
66
|
+
#teLogger.debug "Write ready-to-compress data : #{val.length}"
|
67
|
+
#@in.write(to_java_bytes(val))
|
68
|
+
|
69
|
+
@eng.setInput(to_java_bytes(val))
|
70
|
+
|
71
|
+
@eng.finish
|
72
|
+
|
73
|
+
baos = java.io.ByteArrayOutputStream.new
|
74
|
+
buf = ::Java::byte[102400].new
|
75
|
+
while not @eng.finished
|
76
|
+
done = @eng.deflate(buf)
|
77
|
+
@os.write(buf,0,done)
|
78
|
+
end
|
79
|
+
|
80
|
+
@os.toByteArray
|
81
|
+
else
|
82
|
+
::Java::byte[0].new
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def final
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
|
2
|
+
require_relative '../data_conversion'
|
3
|
+
|
4
|
+
module Ccrypto
|
5
|
+
module Java
|
6
|
+
class Decompression
|
7
|
+
include DataConversion
|
8
|
+
include TR::CondUtils
|
9
|
+
|
10
|
+
include TeLogger::TeLogHelper
|
11
|
+
teLogger_tag :j_decompression
|
12
|
+
|
13
|
+
def initialize(*args,&block)
|
14
|
+
|
15
|
+
@eng = java.util.zip.Inflater.new
|
16
|
+
|
17
|
+
@os = java.io.ByteArrayOutputStream.new
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
def update(val)
|
22
|
+
teLogger.debug "Given #{val.length} bytes for decompression"
|
23
|
+
if val.length > 0
|
24
|
+
|
25
|
+
@eng.setInput(to_java_bytes(val))
|
26
|
+
|
27
|
+
baos = java.io.ByteArrayOutputStream.new
|
28
|
+
buf = ::Java::byte[102400].new
|
29
|
+
while not @eng.finished
|
30
|
+
done = @eng.inflate(buf)
|
31
|
+
teLogger.debug "Done #{done} bytes"
|
32
|
+
@os.write(buf,0,done)
|
33
|
+
end
|
34
|
+
|
35
|
+
@os.toByteArray
|
36
|
+
|
37
|
+
else
|
38
|
+
::Java::byte[0].new
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def final
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
|
2
|
+
require_relative '../data_conversion'
|
3
|
+
|
4
|
+
module Ccrypto
|
5
|
+
module Java
|
6
|
+
class DigestEngine
|
7
|
+
include TR::CondUtils
|
8
|
+
include DataConversion
|
9
|
+
|
10
|
+
include TeLogger::TeLogHelper
|
11
|
+
|
12
|
+
teLogger_tag :j_digest
|
13
|
+
|
14
|
+
Potential = [
|
15
|
+
|
16
|
+
Ccrypto::SHA1.provider_info("SHA-1"),
|
17
|
+
Ccrypto::SHA224.provider_info("SHA-224"),
|
18
|
+
Ccrypto::SHA256.provider_info("SHA-256"),
|
19
|
+
Ccrypto::SHA384.provider_info("SHA-384"),
|
20
|
+
Ccrypto::SHA512.provider_info("SHA-512"),
|
21
|
+
Ccrypto::SHA512_224.provider_info("SHA-512/224"),
|
22
|
+
Ccrypto::SHA512_256.provider_info("SHA-512/256"),
|
23
|
+
|
24
|
+
Ccrypto::SHA3_224.provider_info("SHA3-224"),
|
25
|
+
Ccrypto::SHA3_256.provider_info("SHA3-256"),
|
26
|
+
Ccrypto::SHA3_384.provider_info("SHA3-384"),
|
27
|
+
Ccrypto::SHA3_512.provider_info("SHA3-512"),
|
28
|
+
|
29
|
+
Ccrypto::BLAKE2b160.provider_info("BLAKE2B-160"),
|
30
|
+
Ccrypto::BLAKE2b256.provider_info("BLAKE2B-256"),
|
31
|
+
Ccrypto::BLAKE2b384.provider_info("BLAKE2B-384"),
|
32
|
+
Ccrypto::BLAKE2b512.provider_info("BLAKE2B-512"),
|
33
|
+
|
34
|
+
Ccrypto::BLAKE2s128.provider_info("BLAKE2S-128"),
|
35
|
+
Ccrypto::BLAKE2s160.provider_info("BLAKE2s-160"),
|
36
|
+
Ccrypto::BLAKE2s224.provider_info("BLAKE2s-224"),
|
37
|
+
Ccrypto::BLAKE2s256.provider_info("BLAKE2s-256"),
|
38
|
+
|
39
|
+
Ccrypto::HARAKA256.provider_info("HARAKA-256"),
|
40
|
+
Ccrypto::HARAKA512.provider_info("HARAKA-512"),
|
41
|
+
|
42
|
+
Ccrypto::KECCAK224.provider_info("KECCAK-224"),
|
43
|
+
Ccrypto::KECCAK256.provider_info("KECCAK-256"),
|
44
|
+
Ccrypto::KECCAK288.provider_info("KECCAK-288"),
|
45
|
+
Ccrypto::KECCAK384.provider_info("KECCAK-384"),
|
46
|
+
Ccrypto::KECCAK512.provider_info("KECCAK-512"),
|
47
|
+
|
48
|
+
Ccrypto::RIPEMD128.provider_info("RIPEMD128"),
|
49
|
+
Ccrypto::RIPEMD160.provider_info("RIPEMD160"),
|
50
|
+
Ccrypto::RIPEMD256.provider_info("RIPEMD256"),
|
51
|
+
Ccrypto::RIPEMD320.provider_info("RIPEMD320"),
|
52
|
+
|
53
|
+
Ccrypto::SHAKE128_256.provider_info("SHAKE128-256"),
|
54
|
+
Ccrypto::SHAKE256_512.provider_info("SHAKE256-512"),
|
55
|
+
|
56
|
+
Ccrypto::SKEIN1024_1024.provider_info("SKEIN-1024-1024"),
|
57
|
+
Ccrypto::SKEIN1024_384.provider_info("SKEIN-1024-384"),
|
58
|
+
Ccrypto::SKEIN1024_512.provider_info("SKEIN-1024-512"),
|
59
|
+
|
60
|
+
Ccrypto::SKEIN256_128.provider_info("SKEIN-256-128"),
|
61
|
+
Ccrypto::SKEIN256_160.provider_info("SKEIN-256-160"),
|
62
|
+
Ccrypto::SKEIN256_224.provider_info("SKEIN-256-224"),
|
63
|
+
Ccrypto::SKEIN256_256.provider_info("SKEIN-256-256"),
|
64
|
+
|
65
|
+
Ccrypto::SKEIN512_128.provider_info("SKEIN-512-128"),
|
66
|
+
Ccrypto::SKEIN512_160.provider_info("SKEIN-512-160"),
|
67
|
+
Ccrypto::SKEIN512_224.provider_info("SKEIN-512-224"),
|
68
|
+
Ccrypto::SKEIN512_256.provider_info("SKEIN-512-256"),
|
69
|
+
Ccrypto::SKEIN512_384.provider_info("SKEIN-512-384"),
|
70
|
+
Ccrypto::SKEIN512_512.provider_info("SKEIN-512-512"),
|
71
|
+
|
72
|
+
SM3 = Ccrypto::SM3.provider_info("SM3"),
|
73
|
+
WHIRLPOOL = Ccrypto::WHIRLPOOL.provider_info("WHIRLPOOL")
|
74
|
+
]
|
75
|
+
|
76
|
+
def self.supported
|
77
|
+
if @supported.nil?
|
78
|
+
@supported = []
|
79
|
+
probe = java.security.Security.getAlgorithms("MessageDigest").to_a.delete_if { |e| e.include?(".") }
|
80
|
+
Potential.each do |po|
|
81
|
+
@supported << po if probe.include?(po.provider_config)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
@supported
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.is_supported?(eng, prov = nil)
|
88
|
+
if is_empty?(eng)
|
89
|
+
false
|
90
|
+
else
|
91
|
+
|
92
|
+
jceName = algo_jce_map[eng]
|
93
|
+
begin
|
94
|
+
if not_empty?(prov)
|
95
|
+
#java.security.MessageDigest.getInstance(eng.to_s.gsub("_","-"), prov)
|
96
|
+
java.security.MessageDigest.getInstance(jceName, prov)
|
97
|
+
else
|
98
|
+
#java.security.MessageDigest.getInstance(eng.to_s.gsub("_","-"))
|
99
|
+
java.security.MessageDigest.getInstance(jceName)
|
100
|
+
end
|
101
|
+
true
|
102
|
+
rescue java.security.NoSuchAlgorithmException => ex
|
103
|
+
p ex.message
|
104
|
+
false
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.default_algo
|
110
|
+
"SHA256"
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.instance(conf, &block)
|
114
|
+
if block
|
115
|
+
prov = block.call(:jce_provider)
|
116
|
+
if not_empty?(prov)
|
117
|
+
DigestEngine.new(conf.provider_config, prov, &block)
|
118
|
+
else
|
119
|
+
DigestEngine.new(conf.provider_config, &block)
|
120
|
+
end
|
121
|
+
else
|
122
|
+
DigestEngine.new(conf.provider_config, &block)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def self.digest(key, &block)
|
127
|
+
res = engineKeys[key]
|
128
|
+
if is_empty?(res)
|
129
|
+
raise DigestEngine, "Not supported digest engine #{key}"
|
130
|
+
else
|
131
|
+
if block
|
132
|
+
digProv = block.call(:digest_jceProvider)
|
133
|
+
end
|
134
|
+
|
135
|
+
if digProv.nil?
|
136
|
+
DigestEngine.new(res.provider_config)
|
137
|
+
else
|
138
|
+
DigestEngine.new(res.provider_config, digProv)
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def self.engineKeys
|
144
|
+
if @engineKeys.nil?
|
145
|
+
@engineKeys = {}
|
146
|
+
supported.each do |a|
|
147
|
+
@engineKeys[a.algo.to_sym] = a
|
148
|
+
end
|
149
|
+
end
|
150
|
+
@engineKeys
|
151
|
+
end
|
152
|
+
|
153
|
+
def self.algo_jce_map
|
154
|
+
if @algoMap.nil?
|
155
|
+
@algoMap = {}
|
156
|
+
supported.each do |a|
|
157
|
+
@algoMap[a.algo.to_sym] = a.provider_config
|
158
|
+
end
|
159
|
+
end
|
160
|
+
@algoMap
|
161
|
+
end
|
162
|
+
|
163
|
+
def initialize(algo, prov = nil, &block)
|
164
|
+
teLogger.debug "Algo : #{algo}"
|
165
|
+
@algo = algo #algo.to_s.gsub("_","-")
|
166
|
+
begin
|
167
|
+
if not_empty?(prov)
|
168
|
+
@inst = java.security.MessageDigest.getInstance(@algo, prov)
|
169
|
+
else
|
170
|
+
@inst = java.security.MessageDigest.getInstance(@algo)
|
171
|
+
end
|
172
|
+
#rescue java.security.NoSuchAlgorithmException => ex
|
173
|
+
rescue Exception => ex
|
174
|
+
raise DigestEngineException, ex
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
def digest(val, output = :binary)
|
179
|
+
digest_final(val, output)
|
180
|
+
end
|
181
|
+
|
182
|
+
def digest_update(val)
|
183
|
+
@inst.update(to_java_bytes(val))
|
184
|
+
end
|
185
|
+
|
186
|
+
def digest_final(val = nil, output = :binary)
|
187
|
+
if not_empty?(val)
|
188
|
+
@inst.update(to_java_bytes(val))
|
189
|
+
end
|
190
|
+
res = @inst.digest
|
191
|
+
@inst.reset
|
192
|
+
case output
|
193
|
+
when :hex
|
194
|
+
to_hex(res)
|
195
|
+
when :b64
|
196
|
+
to_b64(res)
|
197
|
+
else
|
198
|
+
res
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def reset
|
203
|
+
@inst.reset
|
204
|
+
end
|
205
|
+
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|