lib/pkernel_jce/keypair.rb in pkernel_jce-0.3 vs lib/pkernel_jce/keypair.rb in pkernel_jce-0.7.0

- old
+ new

@@ -2,23 +2,15 @@ require 'pkernel' require_relative 'provider' require_relative 'global' +require_relative 'converter' + module PkernelJce module KeyPair - def KeyPair.capabilities(type) - case type - when :rsa - when :dsa - when :ecc - else - {} - end - end - def generate(algo, conf = {}) log = conf[:log] if log.nil? log = GConf.instance.glog @@ -38,10 +30,11 @@ kpg = java.security.KeyPairGenerator.getInstance("RSA", prov) end kpg.java_send :initialize, [Java::int], len kpg.generate_key_pair + when "DSA" len = conf[:len] || 2048 log.debug "Generating DSA #{len} bits with provider #{prov == nil ? 'default' : prov.name}" if prov.nil? kpg = java.security.KeyPairGenerator.getInstance("DSA") @@ -52,10 +45,21 @@ kpg.java_send :initialize, [Java::int], len kpg.generate_key_pair when "ECC","EC" # this only supported by bc? curve = conf[:curve] || "prime256v1" + curve.strip! + # Fp + # X9.62 : prime192v1, prime192v2, prime192v3, prime239v1, prime239v2, prime239v3, prime256v1 + # SEC : secp192k1, secp192r1, secp224k1, secp224r1, secp256k1, secp256r1, secp384r1, secp521r1 + # NIST: P-224, P-256, P-384, P-521 + # F 2m + # X9.62 : c2pnb163v1, c2pnb163v2, c2pnb163v3, c2pnb176w1, c2tnb191v1, c2tnb191v2, c2tnb191v3, c2pnb208w1, c2tnb239v1, c2tnb239v2, c2tnb239v3, c2pnb272w1, c2pnb304w1, c2tnb359v1, c2pnb368w1, c2tnb431r1 + # SEC: sect163k1, sect163r1, sect163r2, sect193r1, sect193r2, sect233k1, sect233r1, sect239k1, sect283k1, sect283r1, sect409k1, sect409r1, sect571k1, sect571r1 + # NIST : B-163, B-233, B-283, B-409, B-571 + # Teletrust : brainpoolp160r1, brainpoolp160t1, brainpoolp192r1, brainpoolp192t1, brainpoolp224r1, brainpoolp224t1, brainpoolp256r1, brainpoolp256t1, brainpoolp320r1, brainpoolp320t1, brainpoolp384r1, brainpoolp384t1, brainpoolp512r1, brainpoolp512t1 + # GostR3410-2001-CryptoPro-A, GostR3410-2001-CryptoPro-XchB, GostR3410-2001-CryptoPro-XchA, GostR3410-2001-CryptoPro-C, GostR3410-2001-CryptoPro-B if prov.nil? #kpg = java.security.KeyPairGenerator.getInstance("ECDSA") # default Java does not have ECDSA yet as of Java 8 prov = PkernelJce::Provider.add_default end @@ -63,41 +67,104 @@ PkernelJce::Provider.add_provider(prov) kpg = java.security.KeyPairGenerator.getInstance("ECDSA", prov) kpg.java_send :initialize, [java.security.spec.AlgorithmParameterSpec, java.security.SecureRandom], java.security.spec.ECGenParameterSpec.new(curve), java.security.SecureRandom.new kpg.generate_key_pair + + when "DH" + + len = conf[:len] || 1024 + certainty = conf[:certainty] || org.bouncycastle.jcajce.provider.asymmetric.util.PrimeCertaintyCalculator.getDefaultCertainty(len) + # for DH key, these two values can be shared... + # https://news.ycombinator.com/item?id=10397326 + # this two values shall be in hex + p = conf[:p] + g = conf[:g] + + if not p.nil? + p = java.math.BigInteger.new(p,16) + end + + if not g.nil? + g = java.math.BigInteger.new(g,16) + end + + prov = PkernelJce::Provider::DefProvider + + if not (p.nil? and g.nil?) + log.debug "Generating DH key from given p and g" + gparam = org.bouncycastle.crypto.params.DHParameters.new(p,g) + + else + + log.debug "Generating DH #{len} bits with provider #{prov.name}, certainty : #{certainty}." + if len > 1024 + log.warn "Generating #{len} bits of DH key may take some time... so be patient..." + end + + dhParamGen = org.bouncycastle.crypto.generators.DHParametersGenerator.new + dhParamGen.init(len,certainty, java.security.SecureRandom.new) + gparam = dhParamGen.generate_parameters + end + + kgParam = org.bouncycastle.crypto.params.DHKeyGenerationParameters.new(java.security.SecureRandom.new, gparam) + kpg = org.bouncycastle.crypto.generators.DHKeyPairGenerator.new + kpg.init(kgParam) + kpg.generateKeyPair + else log.error "Unknown '#{algo}' for java keypair" raise PkernelJce::Error, "Unknown algo '#{algo}' for java keypair" end end # end generate # def KeyPair.key_type(key) - if key.java_kind_of?(java.security.KeyPair) + + case key + when java.security.KeyPair, org.bouncycastle.crypto.AsymmetricCipherKeyPair privKey = key.getPrivate else # given is private key - privKey = key + if KeyPair.is_private_key?(key) + privKey = key + else + raise PkernelJce::Error, "key_type API only check for keypair and private key. For public key type shall call pub_key_type() API. Given key is #{key}" + end end - + case privKey - when java.security.interfaces.RSAPrivateCrtKey + when java.security.interfaces.RSAPrivateCrtKey, Java::OrgBouncycastleCryptoParams::RSAPrivateCrtKeyParameters Pkernel::KeyPair::RSA_KEY_NAME - when Java::sun.security.provider.DSAPrivateKey, org.bouncycastle.jcajce.provider.asymmetric.dsa.BCDSAPrivateKey + when Java::sun.security.provider.DSAPrivateKey, org.bouncycastle.jcajce.provider.asymmetric.dsa.BCDSAPrivateKey, Java::OrgBouncycastleCryptoParams::DSAPrivateKeyParameters Pkernel::KeyPair::DSA_KEY_NAME - when org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey + when org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey, Java::OrgBouncycastleCryptoParams::ECPrivateKeyParameters, Java::SunSecurityEc::ECPrivateKeyImpl Pkernel::KeyPair::EC_KEY_NAME + when org.bouncycastle.crypto.params.DHPrivateKeyParameters + Pkernel::KeyPair::DH_KEY_NAME else raise PkernelJce::Error, "Unknown priv key type '#{privKey.class}'" end end # # end get_key_type # + def KeyPair.is_private_key?(key) + if key.nil? + false + else + case key + when java.security.interfaces.RSAPrivateCrtKey, Java::sun.security.provider.DSAPrivateKey, org.bouncycastle.jcajce.provider.asymmetric.dsa.BCDSAPrivateKey, org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey, Java::OrgBouncycastleCryptoParams::RSAPrivateCrtKeyParameters, Java::OrgBouncycastleCryptoParams::DSAPrivateKeyParameters, Java::OrgBouncycastleCryptoParams::ECPrivateKeyParameters, Java::SunSecurityEc::ECPrivateKeyImpl, org.bouncycastle.crypto.AsymmetricCipherKeyPair, java.security.KeyPair + true + else + false + end + end + end + def KeyPair.pub_key_type(key) if key.java_kind_of?(java.security.KeyPair) pubKey = key.public elsif PkernelJce::Certificate.is_cert_object?(key) pubKey = PkernelJce::Certificate.public_key(key) @@ -108,12 +175,14 @@ case pubKey when java.security.interfaces.RSAPublicKey Pkernel::KeyPair::RSA_KEY_NAME when Java::sun.security.provider.DSAPublicKey, Java::OrgBouncycastleJcajceProviderAsymmetricDsa::BCDSAPublicKey Pkernel::KeyPair::DSA_KEY_NAME - when Java::OrgBouncycastleJcajceProviderAsymmetricEc::BCECPublicKey + when Java::OrgBouncycastleJcajceProviderAsymmetricEc::BCECPublicKey, Java::SunSecurityEc::ECPublicKeyImpl Pkernel::KeyPair::EC_KEY_NAME + when org.bouncycastle.crypto.params.DHPublicKeyParameters + Pkernel::KeyPair::DH_KEY_NAME else raise PkernelJce::Error, "Unknown pub key type '#{pubKey.class}'" end end @@ -132,23 +201,10 @@ false end end end - def KeyPair.is_private_key?(key) - if key.nil? - false - else - case key - when java.security.interfaces.RSAPrivateCrtKey, Java::sun.security.provider.DSAPrivateKey, org.bouncycastle.jcajce.provider.asymmetric.dsa.BCDSAPrivateKey, org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey - true - else - false - end - end - end - def KeyPair.is_keypair?(key) if key.nil? false else case key @@ -158,11 +214,11 @@ false end end end - def KeyPair.public_key(priv) + def KeyPair.public_key(priv, opts = { }) if priv.nil? raise PkernelJce::Error, "Cannot derive public key from nil key" else if priv.java_kind_of?(java.security.KeyPair) priv.getPublic @@ -175,15 +231,44 @@ y = priv.params.g.to_java.modPow(priv.x, priv.params.p) spec = java.security.spec.DSAPublicKeySpec.new(y, priv.params.p, priv.params.q, priv.params.g) prov = PkernelJce::Provider.add_default java.security.KeyFactory.getInstance("DSA",prov).generatePublic(spec) when Pkernel::KeyPair::EC_KEY_NAME - d = priv.d; - q = priv.parameters.g.to_java.multiply(d); - pubSpec = org.bouncycastle.jce.spec.ECPublicKeySpec.new(q, priv.parameters); - prov = PkernelJce::Provider.add_default - java.security.KeyFactory.getInstance("EC",prov).generatePublic(pubSpec) + case priv + # No way to recover public key using SUN provider yet + #when Java::SunSecurityEc::ECPrivateKeyImpl + # this uses BC also so add provider first + #pProv = PkernelJce::Provider.add_default + #curveName = priv.params.name.split(" ")[0] + + #ecSpec = org.bouncycastle.jcajce.provider.asymmetric.util.EC5Util.convertSpec(priv.params,false) + #q = ecSpec.g.to_java.multiply(priv.s) + #bcW = ecSpec.curve.decodePoint(q.getEncoded(false)) + ##w = org.bouncycastle.math.ec.ECPoint.new(bcW.getAffineXCoord.toBigInteger, bcW.getAffineYCoord.toBigInteger) + #w = java.security.spec.ECPoint.new(bcW.getAffineXCoord.toBigInteger, bcW.getAffineYCoord.toBigInteger) + #curveParam = org.bouncycastle.jce.ECNamedCurveTable.getParameterSpec(curveName) + ##keySpec = org.bouncycastle.jce.spec.ECPublicKeySpec.new(w,curveParam) + #keySpec = java.security.spec.ECPublicKeySpec.new(w,curveParam) + + ##java.security.KeyFactory.getInstance("EC",pProv).generatePublic(keySpec) + + when Java::OrgBouncycastleCryptoParams::ECPrivateKeyParameters, org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey + d = priv.d + q = priv.parameters.g.to_java.multiply(d) + pubSpec = org.bouncycastle.jce.spec.ECPublicKeySpec.new(q, priv.parameters) + prov = PkernelJce::Provider.add_default + java.security.KeyFactory.getInstance("EC",prov).generatePublic(pubSpec) + else + raise PkernelJce::Error, "Haven't figure out how to convert #{priv.class} into public key yet..." + end + #p priv + #p priv.methods.sort + #d = priv.d; + #q = priv.parameters.g.to_java.multiply(d); + #pubSpec = org.bouncycastle.jce.spec.ECPublicKeySpec.new(q, priv.parameters); + #prov = PkernelJce::Provider.add_default + #java.security.KeyFactory.getInstance("EC",prov).generatePublic(pubSpec) else end elsif priv.java_kind_of?(java.security.PublicKey) priv elsif priv.java_kind_of?(org.bouncycastle.asn1.x509.SubjectPublicKeyInfo) @@ -198,10 +283,25 @@ end end # end public_key(priv) # + # + # Compare 2 public keys + # + def KeyPair.is_public_key_equals?(pub1, pub2) + if not (pub1.nil? and pub2.nil?) + pubkey1 = KeyPair.public_key(pub1) + pubkey2 = KeyPair.public_key(pub2) + + pubkey1.equals(pubkey2) + + else + false + end + end # is_public_key_equals? + # harmonize the private key acquiring # There are BC and Java, keypair and private key def KeyPair.private_key(kp) if kp.nil? raise PkernelJce::Error, "Cannot derive private key from nil private key" @@ -245,57 +345,170 @@ else raise PkernelJce::Error, "Unsupported type to derive signing algo '#{type}'" end end - def dump(keypair, options = {}) + def KeyPair.key_size(kp) + if KeyPair.is_keypair?(kp) + type = PkernelJce::KeyPair.key_type(KeyPair.private_key(kp)) + elsif KeyPair.is_public_key?(kp) + type = PkernelJce::KeyPair.pub_key_type(kp) + elsif Certificate.is_cert_object?(kp) + type = PkernelJce::KeyPair.pub_key_type(Certificate.public_key(kp)) + elsif KeyPair.is_private_key?(kp) + type = PkernelJce::KeyPair.key_type(kp) + else + raise PkernelJce::Error, "Unknown key type to derive signing key algo from" + end + + case type + when Pkernel::KeyPair::RSA_KEY_NAME + if PkernelJce::KeyPair::is_keypair?(kp) + rsaKey = PkernelJce::KeyPair.private_key(kp) + elsif PkernelJce::KeyPair::is_private_key?(kp) + rsaKey = PkernelJce::KeyPair.private_key(kp) + elsif PkernelJce::KeyPair::is_public_key?(kp) + rsaKey = PkernelJce::KeyPair::public_key(kp) + end + + rsaKey.modulus.bit_length + + when Pkernel::KeyPair::DSA_KEY_NAME + if PkernelJce::KeyPair::is_keypair?(kp) + dsaKey = PkernelJce::KeyPair.private_key(kp) + elsif PkernelJce::KeyPair::is_private_key?(kp) + dsaKey = PkernelJce::KeyPair.private_key(kp) + elsif PkernelJce::KeyPair::is_public_key?(kp) + dsaKey = PkernelJce::KeyPair::public_key(kp) + end + + dsaKey.params.p.bit_length + + when Pkernel::KeyPair::EC_KEY_NAME + + end + end + + def dump(keypair, options = {} ,&block) if keypair.nil? raise PkernelJce::Error, "Keypair is nil during writing PEM" end # outputStream only make sense in Java world #os = options[:outputStream] file = options[:file] pass = options[:password] - binOut = java.io.ByteArrayOutputStream.new + #binOut = java.io.ByteArrayOutputStream.new - if file.nil? - PkernelJce::GConf.instance.glog.debug "Dump output to memory" - # return binary to caller - writer = org.bouncycastle.openssl.jcajce.JcaPEMWriter.new(java.io.OutputStreamWriter.new(binOut)); - else - PkernelJce::GConf.instance.glog.debug "Dump output to file '#{file}'" - out = java.io.FileOutputStream.new(file) - writer = org.bouncycastle.openssl.jcajce.JcaPEMWriter.new(java.io.OutputStreamWriter.new(out)); + if (pass.nil? or pass.empty?) and block + pass = block.call(:prompt_pass) end - begin - if pass.nil? or pass.empty? - writer.writeObject(keypair.getPrivate) - else - builder = org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8EncryptorBuilder.new(org.bouncycastle.openssl.PKCS8Generator::AES_256_CBC).setProvider(PkernelJce::Provider::DefProvider).setPasssword(pass.to_java.toCharArray()); + ## BC API + #if file.nil? + # PkernelJce::GConf.instance.glog.debug "Dump output to memory" + # # return binary to caller + # writer = org.bouncycastle.openssl.jcajce.JcaPEMWriter.new(java.io.OutputStreamWriter.new(binOut)); + #else + # PkernelJce::GConf.instance.glog.debug "Dump output to file '#{file}'" + # out = java.io.FileOutputStream.new(file) + # writer = org.bouncycastle.openssl.jcajce.JcaPEMWriter.new(java.io.OutputStreamWriter.new(out)); + #end - pkcs8 = org.bouncycastle.openssl.jcajce.JcaPKCS8Generator.new(keypair.getPrivate, builder.build); - writer.writeObject(pkcs8) + #begin + # if pass.nil? or pass.empty? + # writer.writeObject(keypair.getPrivate) + # else + # builder = org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8EncryptorBuilder.new(org.bouncycastle.openssl.PKCS8Generator::AES_256_CBC).setProvider(PkernelJce::Provider::DefProvider).setPasssword(pass.to_java.toCharArray()); + + # pkcs8 = org.bouncycastle.openssl.jcajce.JcaPKCS8Generator.new(keypair.getPrivate, builder.build); + # writer.writeObject(pkcs8) + # end + #ensure + # writer.flush + # writer.close + #end + + # Java API + prov = options[:provider] + if not prov.nil? + prov = PkernelJce::Provider.add_provider(prov) + end + + if pass.nil? or pass.empty? + PkernelJce::GConf.instance.glog.warn "Dumping of private key without password!" + encInfo = java.security.spec.PKCS8EncodedKeySpec.new(PkernelJce::KeyPair.private_key(keypair).encoded) + else + pbeAlgo = options[:pbeAlgo] + # todo test this algo with openssl and see... + pbeAlgo = "PBEWithSHA1AndRC4_128" if pbeAlgo.nil? or pbeAlgo.empty? + + salt = Java::byte[32].new + Java::JavaSecurity::SecureRandom.new.nextBytes(salt) + pbeParamSpec = Java::JavaxCryptoSpec::PBEParameterSpec.new(salt,88) + pbeKeySpec = Java::JavaxCryptoSpec::PBEKeySpec.new(pass.to_java.toCharArray) + if not prov.nil? + + secKeyFact = Java::JavaxCrypto::SecretKeyFactory.getInstance(pbeAlgo,prov) + pbeKey = secKeyFact.generateSecret(pbeKeySpec) + cipher = Java::JavaxCrypto::Cipher.getInstance(pbeAlgo,prov) + cipher.init(Java::JavaxCrypto::Cipher::ENCRYPT_MODE,pbeKey,pbeParamSpec) + output = cipher.doFinal(PkernelJce::KeyPair.private_key(keypair).getEncoded()) + algoParam = Java::JavaSecurity::AlgorithmParameters.getInstance(pbeAlgo,prov) + + else + secKeyFact = Java::JavaxCrypto::SecretKeyFactory.getInstance(pbeAlgo) + pbeKey = secKeyFact.generateSecret(pbeKeySpec) + cipher = Java::JavaxCrypto::Cipher.getInstance(pbeAlgo) + cipher.init(Java::JavaxCrypto::Cipher::ENCRYPT_MODE,pbeKey,pbeParamSpec) + output = cipher.doFinal(PkernelJce::KeyPair.private_key(keypair).getEncoded()) + algoParam = Java::JavaSecurity::AlgorithmParameters.getInstance(pbeAlgo) end - ensure - writer.flush - writer.close + + algoParam.init(pbeParamSpec) + encPrivInfo = Java::JavaxCrypto::EncryptedPrivateKeyInfo.new(algoParam,output) + encInfo = encPrivInfo end - if file.nil? - binOut.toByteArray + cont = [] + keyType = KeyPair.key_type(keypair) + case keyType + when Pkernel::KeyPair::RSA_KEY_NAME + cont << "-----BEGIN RSA PRIVATE KEY-----" + cont << PkernelJce::Converter.to_mb64(encInfo.getEncoded) + cont << "-----END RSA PRIVATE KEY-----" + when Pkernel::KeyPair::DSA_KEY_NAME + cont << "-----BEGIN DSA PRIVATE KEY-----" + cont << PkernelJce::Converter.to_mb64(encInfo.getEncoded) + cont << "-----END DSA PRIVATE KEY-----" + when Pkernel::KeyPair::EC_KEY_NAME + cont << "-----BEGIN EC PRIVATE KEY-----" + cont << PkernelJce::Converter.to_mb64(encInfo.getEncoded) + cont << "-----END EC PRIVATE KEY-----" + else + raise PkernelJce::Error, "Unsupported key type #{keyType}" end + + pkcs8Envelope = cont.join("\n") + + #pkcs8Envelope = encPrivInfo.getEncoded() + + if not file.nil? + fos = java.io.FileOutputStream.new(file) + fos.write(pkcs8Envelope.to_java.getBytes) + fos.flush + fos.close + end + + pkcs8Envelope + end # end dump def load(opts = {}, &block) - #is = opts[:inputStream] - #if is.nil? - # raise PkernelJce::Error, "InputStream not given" - #end + file = opts[:file] bin = opts[:bin] baos = java.io.ByteArrayOutputStream.new @@ -317,43 +530,148 @@ baos.write(bin) else raise PkernelJce::Error, "No 'file' or 'bin' is defined to load keypair" end - prov = opts[:provider] || PkernelJce::Provider::DefProvider - prov = PkernelJce::Provider.add_provider(prov) + prov = opts[:provider] + if not prov.nil? + prov = PkernelJce::Provider.add_provider(prov) + end - reader = org.bouncycastle.openssl.PEMParser.new(java.io.InputStreamReader.new(java.io.ByteArrayInputStream.new(baos.toByteArray))) - obj = reader.readObject - #p obj.inspect - #p obj.methods.sort - #p obj.java_kind_of?(org.bouncycastle.openssl.PEMEncryptedKeyPair) - if obj.is_a?(org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo) - pass = opts[:password] - if pass.nil? - if block - pass = block.call(:password) - else - raise PkernelJce::Error, "PEM key is encrypted. Please provide a password to load the key." - end + pass = opts[:password] + if (pass.nil? or pass.empty?) and block + pass = block.call(:prompt_pass) + end + + cont = String.from_java_bytes(baos.toByteArray) + cont.gsub!("-----BEGIN RSA PRIVATE KEY-----","") + cont.gsub!("-----END RSA PRIVATE KEY-----","") + cont.gsub!("-----BEGIN DSA PRIVATE KEY-----","") + cont.gsub!("-----END DSA PRIVATE KEY-----","") + cont.gsub!("-----BEGIN EC PRIVATE KEY-----","") + cont.gsub!("-----END EC PRIVATE KEY-----","") + econt = PkernelJce::Converter.from_mb64(cont) + #fos = java.io.FileOutputStream.new("test.bin") + #fos.write(econt) + #fos.flush + #fos.close + + # Java API + if not (pass.nil? or pass.empty?) + + PkernelJce::GConf.instance.glog.debug "Password protected envelope" + encPrivInfo = Java::JavaxCrypto::EncryptedPrivateKeyInfo.new(econt) + cipher = Java::JavaxCrypto::Cipher::getInstance(encPrivInfo.getAlgName()) + pbeKeySpec = Java::JavaxCryptoSpec::PBEKeySpec.new(pass.to_java.toCharArray) + if(prov != nil) + secKeyFact = Java::JavaxCrypto::SecretKeyFactory.getInstance(encPrivInfo.getAlgName(),prov) + else + secKeyFact = Java::JavaxCrypto::SecretKeyFactory.getInstance(encPrivInfo.getAlgName()) end - decProv = org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder.new.setProvider(PkernelJce::Provider::DefProvider).build(pass.to_java.toCharArray) - keyinfo = obj.decryptPrivateKeyInfo(decProv) + pbeKey = secKeyFact.generateSecret(pbeKeySpec) - converter = org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter.new - converter.getPrivateKey(keyinfo) + cipher.init(Java::JavaxCrypto::Cipher::DECRYPT_MODE, pbeKey,encPrivInfo.getAlgParameters()) + + pkcs8KeySpec = encPrivInfo.getKeySpec(cipher) + #privKeyParam = Java::OrgBouncycastleCryptoUtil::PrivateKeyFactory::createKey(pkcs8KeySpec) else - keySpec = java.security.spec.PKCS8EncodedKeySpec.new(obj.getPrivateKeyInfo.encoded) - # Now it's in a PKCS#8 PrivateKeyInfo structure. Read its Algorithm - # OID and use that to construct a KeyFactory. - bIn = org.bouncycastle.asn1.ASN1InputStream.new(java.io.ByteArrayInputStream.new(keySpec.getEncoded())); - pki = org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(bIn.readObject()); - algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId(); - java.security.KeyFactory.getInstance(algOid,prov).generatePrivate(keySpec); + pkcs8KeySpec = java.security.spec.PKCS8EncodedKeySpec.new(econt) + end + + key = org.bouncycastle.crypto.util.PrivateKeyFactory::createKey(java.io.ByteArrayInputStream.new(pkcs8KeySpec.getEncoded)) + keyType = KeyPair.key_type(key) + case keyType + when Pkernel::KeyPair::RSA_KEY_NAME - #privKey = java.security.KeyFactory.getInstance("RSA").generatePrivate(keySpec) - #privKey + if prov.nil? + keyFact = Java::JavaSecurity::KeyFactory.getInstance("RSA") + else + keyFact = Java::JavaSecurity::KeyFactory.getInstance("RSA",prov) + end + #privKey = keyFact.generatePrivate(pkcs8KeySpec) + ## here is how to convert into RSAPublicKey, become keypair! + #pubKeySpec = Java::JavaSecuritySpec::RSAPublicKeySpec.new(privKey.getModulus(),privKey.getPublicExponent()) + #pubKey = keyFact.generatePublic(pubKeySpec) + + #Java::JavaSecurity::KeyPair.new(pubKey,privKey) + + when Pkernel::KeyPair::DSA_KEY_NAME + + if prov.nil? + keyFact = Java::JavaSecurity::KeyFactory.getInstance("DSA") + else + keyFact = Java::JavaSecurity::KeyFactory.getInstance("DSA",prov) + end + + when Pkernel::KeyPair::EC_KEY_NAME + + if prov.nil? + keyFact = Java::JavaSecurity::KeyFactory.getInstance("EC") + else + keyFact = Java::JavaSecurity::KeyFactory.getInstance("EC",prov) + end + + else + + raise PkernelJce::Error, "Unknown key type #{keyType}" + end + + privKey = keyFact.generatePrivate(pkcs8KeySpec) + ## here is how to convert into RSAPublicKey, become keypair! + #pubKeySpec = Java::JavaSecuritySpec::RSAPublicKeySpec.new(privKey.getModulus(),privKey.getPublicExponent()) + #pubKey = keyFact.generatePublic(pubKeySpec) + + #pubKey = PkernelJce::KeyPair.public_key(privKey) + #Java::JavaSecurity::KeyPair.new(pubKey,privKey) + + privKey + + + #if key.java_kind_of? org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters + # keyFact = Java::JavaSecurity::KeyFactory.getInstance("RSA") + # privKey = keyFact.generatePrivate(pkcs8KeySpec) + # # here is how to convert into RSAPublicKey, become keypair! + # pubKeySpec = Java::JavaSecuritySpec::RSAPublicKeySpec.new(privKey.getModulus(),privKey.getPublicExponent()) + # pubKey = keyFact.generatePublic(pubKeySpec) + + # Java::JavaSecurity::KeyPair.new(pubKey,privKey) + #else + # raise PkernelJce::Error, "Unsupported PKCS8 store of type #{key}" + #end + + # BC API + #reader = org.bouncycastle.openssl.PEMParser.new(java.io.InputStreamReader.new(java.io.ByteArrayInputStream.new(baos.toByteArray))) + #obj = reader.readObject + ##p obj.inspect + ##p obj.methods.sort + ##p obj.java_kind_of?(org.bouncycastle.openssl.PEMEncryptedKeyPair) + #if obj.is_a?(org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo) + # pass = opts[:password] + # if pass.nil? + # if block + # pass = block.call(:password) + # else + # raise PkernelJce::Error, "PEM key is encrypted. Please provide a password to load the key." + # end + # end + # decProv = org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder.new.setProvider(PkernelJce::Provider::DefProvider).build(pass.to_java.toCharArray) + # keyinfo = obj.decryptPrivateKeyInfo(decProv) + + # converter = org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter.new + # converter.getPrivateKey(keyinfo) + #else + # keySpec = java.security.spec.PKCS8EncodedKeySpec.new(obj.getPrivateKeyInfo.encoded) + # # Now it's in a PKCS#8 PrivateKeyInfo structure. Read its Algorithm + # # OID and use that to construct a KeyFactory. + # bIn = org.bouncycastle.asn1.ASN1InputStream.new(java.io.ByteArrayInputStream.new(keySpec.getEncoded())); + # pki = org.bouncycastle.asn1.pkcs.PrivateKeyInfo.getInstance(bIn.readObject()); + # algOid = pki.getPrivateKeyAlgorithm().getAlgorithm().getId(); + # java.security.KeyFactory.getInstance(algOid,prov).generatePrivate(keySpec); + # + # #privKey = java.security.KeyFactory.getInstance("RSA").generatePrivate(keySpec) + # #privKey + #end end # end load() #