lib/ccrypto/java/engines/digest_engine.rb in ccrypto-java-0.1.0 vs lib/ccrypto/java/engines/digest_engine.rb in ccrypto-java-0.2.0
- old
+ new
@@ -5,203 +5,285 @@
module Java
class DigestEngine
include TR::CondUtils
include DataConversion
- include TeLogger::TeLogHelper
+ class SupportedDigestEngine
+ include InMemoryRecord
- teLogger_tag :j_digest
+ def initialize
+ define_search_key(:algo, :outBitLength, :outByteLength)
+ end
+ end
- Potential = [
+ def self.supported
+ if @supported.nil?
+ if ENV[Java::ENV_PROBE_DIGEST_KEY] == "true"
+ @supported = SupportedDigestEngine.new
+ else
+ @supported = SupportedDigestEngine.load_from_storage("supported_digest")
+ end
- Ccrypto::SHA1.provider_info("SHA-1"),
- Ccrypto::SHA224.provider_info("SHA-224"),
- Ccrypto::SHA256.provider_info("SHA-256"),
- Ccrypto::SHA384.provider_info("SHA-384"),
- Ccrypto::SHA512.provider_info("SHA-512"),
- Ccrypto::SHA512_224.provider_info("SHA-512/224"),
- Ccrypto::SHA512_256.provider_info("SHA-512/256"),
+ if @supported.empty?
+ @supported = SupportedDigestEngine.new
+ probe = java.security.Security.getAlgorithms("MessageDigest").to_a.delete_if { |e| e.include?(".") }
- Ccrypto::SHA3_224.provider_info("SHA3-224"),
- Ccrypto::SHA3_256.provider_info("SHA3-256"),
- Ccrypto::SHA3_384.provider_info("SHA3-384"),
- Ccrypto::SHA3_512.provider_info("SHA3-512"),
+ logger = Ccrypto::Java.logger(:digest_eng)
- Ccrypto::BLAKE2b160.provider_info("BLAKE2B-160"),
- Ccrypto::BLAKE2b256.provider_info("BLAKE2B-256"),
- Ccrypto::BLAKE2b384.provider_info("BLAKE2B-384"),
- Ccrypto::BLAKE2b512.provider_info("BLAKE2B-512"),
+ blacklistedDigest = ["MD2","MD4","MD5"]
+ probe.sort.each do |found|
+ next if blacklistedDigest.include?(found)
+ logger.debug "Found digest algo : #{found}"
+ begin
+ md = java.security.MessageDigest.getInstance(found, JCEProvider::BCProv)
+ case found
+ when "HARAKA-256"
+ conf = { provider_config: { algo_name: found, jceProvider: JCEProvider::BCProv.name }, fixed_input_len_byte: 32 }
+ when "HARAKA-512"
+ conf = { provider_config: { algo_name: found, jceProvider: JCEProvider::BCProv.name }, fixed_input_len_byte: 64 }
+ else
+ conf = { provider_config: { algo_name: found, jceProvider: JCEProvider::BCProv.name } }
+ end
- Ccrypto::BLAKE2s128.provider_info("BLAKE2S-128"),
- Ccrypto::BLAKE2s160.provider_info("BLAKE2s-160"),
- Ccrypto::BLAKE2s224.provider_info("BLAKE2s-224"),
- Ccrypto::BLAKE2s256.provider_info("BLAKE2s-256"),
+ digConf = Ccrypto::DigestConfig.new(found, md.getDigestLength()*8, conf)
- Ccrypto::HARAKA256.provider_info("HARAKA-256"),
- Ccrypto::HARAKA512.provider_info("HARAKA-512"),
+ testDig = Ccrypto::DigestMatcher.generate_digest(digConf)
+ digKey = Ccrypto::DigestMatcher.find_digest_key(testDig)
+ if not_empty?(digKey)
+ # map the algo name to common name
+ digConf = Ccrypto::DigestConfig.new(digKey, md.getDigestLength()*8, conf)
+ @supported.register(digConf, { tag_under: :jceAlgo, tag_value: found })
- Ccrypto::KECCAK224.provider_info("KECCAK-224"),
- Ccrypto::KECCAK256.provider_info("KECCAK-256"),
- Ccrypto::KECCAK288.provider_info("KECCAK-288"),
- Ccrypto::KECCAK384.provider_info("KECCAK-384"),
- Ccrypto::KECCAK512.provider_info("KECCAK-512"),
+ else
+ logger.warn "Digest algo from Java named '#{found}' not listed in the Ccrypto::DigestMatcher. Skip or add the value into the table. [#{testDig}]"
- Ccrypto::RIPEMD128.provider_info("RIPEMD128"),
- Ccrypto::RIPEMD160.provider_info("RIPEMD160"),
- Ccrypto::RIPEMD256.provider_info("RIPEMD256"),
- Ccrypto::RIPEMD320.provider_info("RIPEMD320"),
+ end
- Ccrypto::SHAKE128_256.provider_info("SHAKE128-256"),
- Ccrypto::SHAKE256_512.provider_info("SHAKE256-512"),
+ rescue Exception => ex
+ logger.error ex.message
+ end
+ end
+ end
- Ccrypto::SKEIN1024_1024.provider_info("SKEIN-1024-1024"),
- Ccrypto::SKEIN1024_384.provider_info("SKEIN-1024-384"),
- Ccrypto::SKEIN1024_512.provider_info("SKEIN-1024-512"),
+ @supported.save_to_storage("supported_digest")
- Ccrypto::SKEIN256_128.provider_info("SKEIN-256-128"),
- Ccrypto::SKEIN256_160.provider_info("SKEIN-256-160"),
- Ccrypto::SKEIN256_224.provider_info("SKEIN-256-224"),
- Ccrypto::SKEIN256_256.provider_info("SKEIN-256-256"),
-
- Ccrypto::SKEIN512_128.provider_info("SKEIN-512-128"),
- Ccrypto::SKEIN512_160.provider_info("SKEIN-512-160"),
- Ccrypto::SKEIN512_224.provider_info("SKEIN-512-224"),
- Ccrypto::SKEIN512_256.provider_info("SKEIN-512-256"),
- Ccrypto::SKEIN512_384.provider_info("SKEIN-512-384"),
- Ccrypto::SKEIN512_512.provider_info("SKEIN-512-512"),
-
- SM3 = Ccrypto::SM3.provider_info("SM3"),
- WHIRLPOOL = Ccrypto::WHIRLPOOL.provider_info("WHIRLPOOL")
- ]
-
- def self.supported
- if @supported.nil?
- @supported = []
- probe = java.security.Security.getAlgorithms("MessageDigest").to_a.delete_if { |e| e.include?(".") }
- Potential.each do |po|
- @supported << po if probe.include?(po.provider_config)
- end
end
@supported
end
+ class << self
+ alias_method :supported_digests, :supported
+ end
- def self.is_supported?(eng, prov = nil)
- if is_empty?(eng)
- false
+ def self.is_digest_supported?(key)
+ (find_digest_config(key).length > 0)
+ end
+
+ def self.instance(conf, &block)
+
+ case conf
+ when String, Symbol
+ digEng = find_digest_config(conf)
+ when Ccrypto::DigestConfig
+ digEng = conf
else
+ raise DigestEngineException, "Unsupported instance type '#{conf}'"
+ end
- jceName = algo_jce_map[eng]
- begin
- if not_empty?(prov)
- #java.security.MessageDigest.getInstance(eng.to_s.gsub("_","-"), prov)
- java.security.MessageDigest.getInstance(jceName, prov)
- else
- #java.security.MessageDigest.getInstance(eng.to_s.gsub("_","-"))
- java.security.MessageDigest.getInstance(jceName)
- end
- true
- rescue java.security.NoSuchAlgorithmException => ex
- p ex.message
- false
- end
+ raise DigestEngineException, "Unsupported digest type '#{conf}'" if digEng.nil?
+
+ prov = digEng.provider_config[:jceProvider]
+ if not_empty?(prov)
+ JCEProvider.instance.add_provider(prov) if not JCEProvider.instance.is_provider_registered?(prov)
+ DigestEngine.new(digEng.provider_config[:algo_name], prov, &block)
+ else
+ DigestEngine.new(digEng.provider_config[:algo_name], &block)
end
+
end
- def self.default_algo
- "SHA256"
+ def self.find_digest_config(key)
+ res = supported.find(algo: key)
+ res.concat(supported.find(jceAlgo: key))
+ res.uniq
end
- def self.instance(conf, &block)
- if block
- prov = block.call(:jce_provider)
- if not_empty?(prov)
- DigestEngine.new(conf.provider_config, prov, &block)
- else
- DigestEngine.new(conf.provider_config, &block)
- end
+ def self.to_bc_digest_inst(conf)
+ case conf
+ when Ccrypto::DigestConfig
+ algo = conf.provider_config[:algo_name]
+ when String
+ algo = conf.upcase
+ when Symbol
+ algo = conf.to_s.upcase
else
- DigestEngine.new(conf.provider_config, &block)
+ raise DigestEngineException, "Unsupported query type '#{conf.class}'"
end
- end
- def self.digest(key, &block)
- res = engineKeys[key]
- if is_empty?(res)
- raise DigestEngine, "Not supported digest engine #{key}"
- else
- if block
- digProv = block.call(:digest_jceProvider)
- end
+ logger.debug "BC digest matching : #{conf.inspect} ==> #{algo}"
- if digProv.nil?
- DigestEngine.new(res.provider_config)
- else
- DigestEngine.new(res.provider_config, digProv)
- end
+ case algo
+ when "BLAKE2B-160","BLAKE2B_160"
+ "org.bouncycastle.crypto.digests.Blake2bDigest.new(160)"
+ when "BLAKE2B-256"
+ "org.bouncycastle.crypto.digests.Blake2bDigest.new(256)"
+ when "BLAKE2B-384"
+ "org.bouncycastle.crypto.digests.Blake2bDigest.new(384)"
+ when "BLAKE2B-512"
+ "org.bouncycastle.crypto.digests.Blake2bDigest.new(512)"
+ when "BLAKE2S-128"
+ "org.bouncycastle.crypto.digests.Blake2sDigest.new(128)"
+ when "BLAKE2S-160"
+ "org.bouncycastle.crypto.digests.Blake2sDigest.new(160)"
+ when "BLAKE2S-224"
+ "org.bouncycastle.crypto.digests.Blake2sDigest.new(224)"
+ when "BLAKE2S-256"
+ "org.bouncycastle.crypto.digests.Blake2sDigest.new(256)"
+ when "BLAKE3-256"
+ "org.bouncycastle.crypto.digests.Blake3Digest.new #(256)"
+ when "DSTU7564-256"
+ "org.bouncycastle.crypto.digests.DSTU7564Digest.new(256)"
+ when "DSTU7564-384"
+ "org.bouncycastle.crypto.digests.DSTU7564Digest.new(384)"
+ when "DSTU7564-512"
+ "org.bouncycastle.crypto.digests.DSTU7564Digest.new(512)"
+ when "GOST3411"
+ "org.bouncycastle.crypto.digests.GOST3411Digest.new"
+ when "GOST3411-2012-256"
+ "org.bouncycastle.crypto.digests.GOST3411_2012_256Digest.new"
+ when "GOST3411-2012-512"
+ "org.bouncycastle.crypto.digests.GOST3411_2012_512Digest.new"
+ #when "HARAKA-256"
+ # org.bouncycastle.crypto.digests.Haraka256Digest.new
+ #when "HARAKA-512"
+ # org.bouncycastle.crypto.digests.Haraka512Digest.new
+ when "KECCAK-224"
+ "org.bouncycastle.crypto.digests.KeccakDigest.new(224)"
+ when "KECCAK-256"
+ "org.bouncycastle.crypto.digests.KeccakDigest.new(256)"
+ when "KECCAK-288"
+ "org.bouncycastle.crypto.digests.KeccakDigest.new(288)"
+ when "KECCAK-384"
+ "org.bouncycastle.crypto.digests.KeccakDigest.new(384)"
+ when "KECCAK-512"
+ "org.bouncycastle.crypto.digests.KeccakDigest.new(512)"
+ when "RIPEMD128"
+ "org.bouncycastle.crypto.digests.RIPEMD128Digest.new"
+ when "RIPEMD160"
+ "org.bouncycastle.crypto.digests.RIPEMD160Digest.new"
+ when "RIPEMD256"
+ "org.bouncycastle.crypto.digests.RIPEMD256Digest.new"
+ when "SHA-1", "SHA1"
+ "org.bouncycastle.crypto.digests.SHA1Digest.new"
+ when "SHA-224", "SHA224"
+ "org.bouncycastle.crypto.digests.SHA224Digest.new"
+ when "SHA-256", "SHA256"
+ "org.bouncycastle.crypto.digests.SHA256Digest.new"
+ when "SHA-384", "SHA384"
+ "org.bouncycastle.crypto.digests.SHA384Digest.new"
+ when "SHA-512", "SHA512"
+ "org.bouncycastle.crypto.digests.SHA512Digest.new"
+ when "SHA3-224","SHA3_224"
+ "org.bouncycastle.crypto.digests.SHA3Digest.new(224)"
+ when "SHA3-256","SHA3_256"
+ "org.bouncycastle.crypto.digests.SHA3Digest.new(256)"
+ when "SHA3-384","SHA3_384"
+ "org.bouncycastle.crypto.digests.SHA3Digest.new(384)"
+ when "SHA3-512","SHA3_512"
+ "org.bouncycastle.crypto.digests.SHA3Digest.new(512)"
+ when "SHAKE128-256","SHAKE128_256"
+ "org.bouncycastle.crypto.digests.SHAKEDigest.new(128)"
+ when "SHAKE256-512","SHAKE256_512"
+ "org.bouncycastle.crypto.digests.SHAKEDigest.new(256)"
+ when "SKEIN-1024-1024","SKEIN_1024_1024"
+ "org.bouncycastle.crypto.digests.SkeinDigest.new(1024,1024)"
+ when "SKEIN-1024-384","SKEIN_1024_384"
+ "org.bouncycastle.crypto.digests.SkeinDigest.new(1024,384)"
+ when "SKEIN-1024-512","SKEIN_1024_512"
+ "org.bouncycastle.crypto.digests.SkeinDigest.new(1024,512)"
+ when "SKEIN-256-128","SKEIN_256_128"
+ "org.bouncycastle.crypto.digests.SkeinDigest.new(256,128)"
+ when "SKEIN-256-160","SKEIN_256_160"
+ "org.bouncycastle.crypto.digests.SkeinDigest.new(256,160)"
+ when "SKEIN-256-224","SKEIN_256_224"
+ "org.bouncycastle.crypto.digests.SkeinDigest.new(256,224)"
+ when "SKEIN-256-256","SKEIN_256_256"
+ "org.bouncycastle.crypto.digests.SkeinDigest.new(256,256)"
+ when "SKEIN-512-128","SKEIN_512_128"
+ "org.bouncycastle.crypto.digests.SkeinDigest.new(512,128)"
+ when "SKEIN-512-160","SKEIN_512_160"
+ "org.bouncycastle.crypto.digests.SkeinDigest.new(512,160)"
+ when "SKEIN-512-224","SKEIN_512_224"
+ "org.bouncycastle.crypto.digests.SkeinDigest.new(512,224)"
+ when "SKEIN-512-256","SKEIN_512_256"
+ "org.bouncycastle.crypto.digests.SkeinDigest.new(512,256)"
+ when "SKEIN-512-384","SKEIN_512_384"
+ "org.bouncycastle.crypto.digests.SkeinDigest.new(512,384)"
+ when "SKEIN-512-512","SKEIN_512_512"
+ "org.bouncycastle.crypto.digests.SkeinDigest.new(512,512)"
+ when "SM3"
+ "org.bouncycastle.crypto.digests.SM3Digest.new"
+ when "TIGER"
+ "org.bouncycastle.crypto.digests.TigerDigest.new"
+ when "WHIRLPOOL"
+ "org.bouncycastle.crypto.digests.WhirlpoolDigest.new"
end
+
end
- def self.engineKeys
- if @engineKeys.nil?
- @engineKeys = {}
- supported.each do |a|
- @engineKeys[a.algo.to_sym] = a
- end
- end
- @engineKeys
- end
- def self.algo_jce_map
- if @algoMap.nil?
- @algoMap = {}
- supported.each do |a|
- @algoMap[a.algo.to_sym] = a.provider_config
- end
- end
- @algoMap
+ private
+ def self.logger
+ Ccrypto::Java.logger(:cj_digest_eng_c)
end
+ public
+ ##
+ # Instance method
+ ##
+ attr_reader :native_instance
def initialize(algo, prov = nil, &block)
- teLogger.debug "Algo : #{algo}"
- @algo = algo #algo.to_s.gsub("_","-")
+
+ logger.debug "Algo : #{algo}"
+
+ @algo = algo
begin
if not_empty?(prov)
- @inst = java.security.MessageDigest.getInstance(@algo, prov)
+ @native_instance = java.security.MessageDigest.getInstance(@algo, prov)
else
- @inst = java.security.MessageDigest.getInstance(@algo)
+ @native_instance = java.security.MessageDigest.getInstance(@algo)
end
- #rescue java.security.NoSuchAlgorithmException => ex
rescue Exception => ex
raise DigestEngineException, ex
end
end
def digest(val, output = :binary)
digest_final(val, output)
end
def digest_update(val)
- @inst.update(to_java_bytes(val))
+ @native_instance.update(to_java_bytes(val))
end
def digest_final(val = nil, output = :binary)
if not_empty?(val)
- @inst.update(to_java_bytes(val))
+ @native_instance.update(to_java_bytes(val))
end
- res = @inst.digest
- @inst.reset
+ res = @native_instance.digest
+ @native_instance.reset
case output
when :hex
to_hex(res)
when :b64
to_b64(res)
else
res
end
end
- def reset
- @inst.reset
+ private
+ def logger
+ Ccrypto::Java.logger(:cj_digest_eng)
end
end
end
end