require 'pkernel' require_relative 'provider' require_relative 'global' require_relative 'converter' module PkernelJce module KeyPair def generate(algo, conf = {}) log = conf[:log] if log.nil? log = GConf.instance.glog end prov = conf[:provider] #log.debug "Provider is #{prov == nil ? 'nil' : prov.name}" case algo.to_s.upcase when "RSA" len = conf[:len] || 2048 log.debug "Generating RSA #{len} bits with provider #{prov == nil ? 'default' : prov.name}" if prov.nil? kpg = java.security.KeyPairGenerator.getInstance("RSA") else PkernelJce::Provider.add_provider(prov) 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") else PkernelJce::Provider.add_provider(prov) kpg = java.security.KeyPairGenerator.getInstance("DSA", prov) end 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 log.debug "Generating ECC curve '#{curve}' with provider #{prov == nil ? 'default' : prov.name}" 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) case key when java.security.KeyPair, org.bouncycastle.crypto.AsymmetricCipherKeyPair privKey = key.getPrivate else # given is private 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, Java::OrgBouncycastleCryptoParams::RSAPrivateCrtKeyParameters Pkernel::KeyPair::RSA_KEY_NAME 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, 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) else pubKey = key end 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, 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 def KeyPair.ensure_java_keypair(kp) raise PkernelJce::Error, "Keypair to check for Java keypair type is nil" if kp.nil? end def KeyPair.is_public_key?(key) if key.nil? false else case key when java.security.interfaces.RSAPublicKey, Java::OrgBouncycastleJcajceProviderAsymmetricDsa::BCDSAPublicKey,Java::sun.security.provider.DSAPublicKey, Java::OrgBouncycastleJcajceProviderAsymmetricEc::BCECPublicKey true else false end end end def KeyPair.is_keypair?(key) if key.nil? false else case key when java.security.KeyPair true else false end end end 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 elsif priv.java_kind_of?(java.security.PrivateKey) type = key_type(priv) case type when Pkernel::KeyPair::RSA_KEY_NAME java.security.KeyFactory.getInstance("RSA").generatePublic(java.security.spec.RSAPublicKeySpec.new(priv.modulus, priv.public_exponent)) when Pkernel::KeyPair::DSA_KEY_NAME 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 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) org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter.new.getPublicKey(priv) elsif priv.java_kind_of?(org.bouncycastle.cert.X509CertificateHolder) org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter.new.getPublicKey(priv.subject_public_key_info) elsif priv.java_kind_of?(java.security.cert.Certificate) priv.public_key else raise PkernelJce::Error, "Unsupported key type '#{priv.class}' to convert to public key" end 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" else case kp when java.security.KeyPair kp.private when java.security.PrivateKey kp else raise PkernelJce::Error, "Unsupported key type '#{kp}' to derive private key from." end end end def KeyPair.derive_signing_algo(kp, hashAlgo = "SHA256") raise PkernelJce::Error, "Hashing algo should not be nil while deriving signing algo" if hashAlgo.nil? PkernelJce::GConf.instance.glog.debug "Derive signing algo for key '#{kp.class}'" 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 #type = PkernelJce::KeyPair.key_type(kp) case type when Pkernel::KeyPair::RSA_KEY_NAME "#{hashAlgo}with#{type.upcase}" when Pkernel::KeyPair::DSA_KEY_NAME "#{hashAlgo}with#{type.upcase}" when Pkernel::KeyPair::EC_KEY_NAME "#{hashAlgo}with#{type.upcase}DSA" else raise PkernelJce::Error, "Unsupported type to derive signing algo '#{type}'" end end 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 if (pass.nil? or pass.empty?) and block pass = block.call(:prompt_pass) end ## 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 #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 algoParam.init(pbeParamSpec) encPrivInfo = Java::JavaxCrypto::EncryptedPrivateKeyInfo.new(algoParam,output) encInfo = encPrivInfo end 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) file = opts[:file] bin = opts[:bin] baos = java.io.ByteArrayOutputStream.new if not file.nil? and not file.empty? PkernelJce::GConf.instance.glog.debug "Load keypair from file '#{file}'" f = java.io.File.new(file) if f.exists? b = Java::byte[f.length].new dis = java.io.DataInputStream.new(java.io.FileInputStream.new(f)) dis.readFully(b) dis.close baos.write(b) else raise PkernelJce::Error, "Given file to load '#{f.absolute_path}' does not exist" end elsif not bin.nil? PkernelJce::GConf.instance.glog.debug "Load keypair from memory" baos.write(bin) else raise PkernelJce::Error, "No 'file' or 'bin' is defined to load keypair" end prov = opts[:provider] if not prov.nil? prov = PkernelJce::Provider.add_provider(prov) 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 pbeKey = secKeyFact.generateSecret(pbeKeySpec) cipher.init(Java::JavaxCrypto::Cipher::DECRYPT_MODE, pbeKey,encPrivInfo.getAlgParameters()) pkcs8KeySpec = encPrivInfo.getKeySpec(cipher) #privKeyParam = Java::OrgBouncycastleCryptoUtil::PrivateKeyFactory::createKey(pkcs8KeySpec) else 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 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() # end class KeyPairEngine extend KeyPair end end