In Ruby i have simple old source line which create RSA public or private keys:
OpenSSL::PKey::RSA.new(File.read(key_file))
My RSA public and private keys formatted like this, i use exactly same key files for MRI and Jruby:
-----BEGIN RSA PRIVATE KEY-----
MIIEvwIBADANBgkq...
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqh...
-----END PUBLIC KEY-----
When i run it on MRI v2.4.0 - any issues, i can instantiate public and private keys:
$> irb
> k = OpenSSL::PKey::RSA.new(File.read("private.pem"))
=> #<OpenSSL::PKey::RSA:0x007fda1096a6a8>
> k = OpenSSL::PKey::RSA.new(File.read("public.pem"))
=> #<OpenSSL::PKey::RSA:0x007fda1096a6a8>
But using Jruby 9.0.4.0 and 9.1.8.0 i can successfully initiate public but failed on init private key:
> set JRUBY_OPTS=-J-Djruby.openssl.debug=true
> irb
irb(main):001:0> require "openssl"
using provider: BC version 1.56
irb(main):002:0> k = OpenSSL::PKey::RSA.new(File.read("public.pem"))
=> #<OpenSSL::PKey::RSA:0x1c9e76b>
But failed on creating private key object:
irb(main):003:0> k = OpenSSL::PKey::RSA.new(File.read("private.pem"))
java.io.IOException: problem creating RSA private key: java.lang.ClassCastException: org.bouncycastle.asn1.DLSequence cannot be ca
st to org.bouncycastle.asn1.ASN1Integer
at org.jruby.ext.openssl.x509store.PEMInputOutput.mapReadException(PEMInputOutput.java:383)
at org.jruby.ext.openssl.x509store.PEMInputOutput.readPrivateKey(PEMInputOutput.java:328)
at org.jruby.ext.openssl.PKey.readPrivateKey(PKey.java:395)
at org.jruby.ext.openssl.PKeyRSA.initialize(PKeyRSA.java:260)
at org.jruby.ext.openssl.PKeyRSA$INVOKER$i$0$0$initialize.call(PKeyRSA$INVOKER$i$0$0$initialize.gen)
at org.jruby.internal.runtime.methods.JavaMethod$JavaMethodN.call(JavaMethod.java:720)
at org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:171)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:177)
at org.jruby.RubyClass.newInstance(RubyClass.java:1001)
at org.jruby.RubyClass$INVOKER$i$newInstance.call(RubyClass$INVOKER$i$newInstance.gen)
at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:200)
at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:338)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:163)
at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:314)
at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:73)
at org.jruby.ir.interpreter.Interpreter.INTERPRET_EVAL(Interpreter.java:122)
at org.jruby.ir.interpreter.Interpreter.evalCommon(Interpreter.java:176)
at org.jruby.ir.interpreter.Interpreter.evalWithBinding(Interpreter.java:200)
at org.jruby.RubyKernel.evalCommon(RubyKernel.java:1033)
at org.jruby.RubyKernel.eval19(RubyKernel.java:1000)
at org.jruby.RubyKernel$INVOKER$s$0$3$eval19.call(RubyKernel$INVOKER$s$0$3$eval19.gen)
at org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:77)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:83)
at org.jruby.ir.instructions.CallBase.interpret(CallBase.java:428)
at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:355)
at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:73)
at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:109)
at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:95)
at org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:77)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:83)
at org.jruby.ir.instructions.CallBase.interpret(CallBase.java:428)
at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:355)
at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:73)
at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:89)
at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:214)
at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:200)
at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:208)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:193)
at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:323)
at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:73)
at org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:132)
at org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:148)
at org.jruby.runtime.IRBlockBody.yieldSpecific(IRBlockBody.java:80)
at org.jruby.runtime.Block.yieldSpecific(Block.java:136)
at org.jruby.ir.runtime.IRRuntimeHelpers.yieldSpecific(IRRuntimeHelpers.java:450)
at org.jruby.ir.instructions.YieldInstr.interpret(YieldInstr.java:74)
at org.jruby.ir.interpreter.StartupInterpreterEngine.processOtherOp(StartupInterpreterEngine.java:187)
at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:111)
at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:83)
at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:179)
at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:165)
at org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:171)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:177)
at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:332)
at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:73)
at org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:132)
at org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:148)
at org.jruby.runtime.IRBlockBody.doYield(IRBlockBody.java:189)
at org.jruby.runtime.BlockBody.yield(BlockBody.java:120)
at org.jruby.runtime.Block.yieldValues(Block.java:183)
at org.jruby.ir.instructions.YieldInstr.interpret(YieldInstr.java:80)
at org.jruby.ir.interpreter.StartupInterpreterEngine.processOtherOp(StartupInterpreterEngine.java:187)
at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:111)
at org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:132)
at org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:148)
at org.jruby.runtime.IRBlockBody.yieldSpecific(IRBlockBody.java:80)
at org.jruby.runtime.Block.yieldSpecific(Block.java:136)
at org.jruby.RubyKernel.loop(RubyKernel.java:1298)
at org.jruby.RubyKernel$INVOKER$s$0$0$loop.call(RubyKernel$INVOKER$s$0$0$loop.gen)
at org.jruby.internal.runtime.methods.JavaMethod$JavaMethodZeroBlock.call(JavaMethod.java:497)
at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:298)
at org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:79)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:83)
at org.jruby.ir.instructions.CallBase.interpret(CallBase.java:428)
at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:355)
at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:73)
at org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:132)
at org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:148)
at org.jruby.runtime.IRBlockBody.doYield(IRBlockBody.java:182)
at org.jruby.runtime.BlockBody.yield(BlockBody.java:111)
at org.jruby.runtime.Block.yield(Block.java:167)
at org.jruby.RubyContinuation.enter(RubyContinuation.java:107)
at org.jruby.RubyKernel.rbCatch19Common(RubyKernel.java:1127)
at org.jruby.RubyKernel.rbCatch19(RubyKernel.java:1120)
at org.jruby.RubyKernel$INVOKER$s$rbCatch19.call(RubyKernel$INVOKER$s$rbCatch19.gen)
at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:348)
at org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:173)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:177)
at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:332)
at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:73)
at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:109)
at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:95)
at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:298)
at org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:79)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:83)
at org.jruby.ir.instructions.CallBase.interpret(CallBase.java:428)
at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:355)
at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:73)
at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:77)
at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:144)
at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:130)
at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:192)
at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:318)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:131)
at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:339)
at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:73)
at org.jruby.ir.interpreter.Interpreter.INTERPRET_BLOCK(Interpreter.java:132)
at org.jruby.runtime.MixedModeIRBlockBody.commonYieldPath(MixedModeIRBlockBody.java:148)
at org.jruby.runtime.IRBlockBody.doYield(IRBlockBody.java:182)
at org.jruby.runtime.BlockBody.yield(BlockBody.java:111)
at org.jruby.runtime.Block.yield(Block.java:167)
at org.jruby.RubyContinuation.enter(RubyContinuation.java:107)
at org.jruby.RubyKernel.rbCatch19Common(RubyKernel.java:1127)
at org.jruby.RubyKernel.rbCatch19(RubyKernel.java:1120)
at org.jruby.RubyKernel$INVOKER$s$rbCatch19.call(RubyKernel$INVOKER$s$rbCatch19.gen)
at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:348)
at org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:173)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:177)
at org.jruby.ir.interpreter.InterpreterEngine.processCall(InterpreterEngine.java:332)
at org.jruby.ir.interpreter.StartupInterpreterEngine.interpret(StartupInterpreterEngine.java:73)
at org.jruby.ir.interpreter.InterpreterEngine.interpret(InterpreterEngine.java:83)
at org.jruby.internal.runtime.methods.MixedModeIRMethod.INTERPRET_METHOD(MixedModeIRMethod.java:179)
at org.jruby.internal.runtime.methods.MixedModeIRMethod.call(MixedModeIRMethod.java:165)
at org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:200)
at org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:338)
at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:163)
at C_3a_.jruby_minus_9_dot_1_dot_8_dot_0.bin.jirb.invokeOther13:start(C:/jruby-9.1.8.0/bin/jirb:13)
at C_3a_.jruby_minus_9_dot_1_dot_8_dot_0.bin.jirb.RUBY$script(C:/jruby-9.1.8.0/bin/jirb:13)
at java.lang.invoke.MethodHandle.invokeWithArguments(Unknown Source)
at org.jruby.ir.Compiler$1.load(Compiler.java:95)
at org.jruby.Ruby.runScript(Ruby.java:827)
at org.jruby.Ruby.runNormally(Ruby.java:746)
at org.jruby.Ruby.runNormally(Ruby.java:764)
at org.jruby.Ruby.runFromMain(Ruby.java:577)
at org.jruby.Main.doRunFromMain(Main.java:417)
at org.jruby.Main.internalRun(Main.java:305)
at org.jruby.Main.run(Main.java:232)
at org.jruby.Main.main(Main.java:204)
Caused by: java.lang.ClassCastException: org.bouncycastle.asn1.DLSequence cannot be cast to org.bouncycastle.asn1.ASN1Integer
at org.jruby.ext.openssl.impl.PKey.readPrivateKey(PKey.java:88)
at org.jruby.ext.openssl.x509store.PEMInputOutput.readKeyPair(PEMInputOutput.java:1242)
at org.jruby.ext.openssl.x509store.PEMInputOutput.readPrivateKey(PEMInputOutput.java:325)
... 136 more
PKeyRSA could not read private key java.io.IOException: unknown tag 13 encountered
PKeyRSA could not read public key java.io.IOException: unknown tag 13 encountered
PKeyRSA could not generate (PKCS8) private key org.bouncycastle.jcajce.provider.asymmetric.util.ExtendedInvalidKeySpecException: u
nable to process key spec: java.lang.IllegalArgumentException: failed to construct sequence from byte[]: unknown tag 13 encountere
d
PKeyRSA could not generate (X509) public key java.security.spec.InvalidKeySpecException: encoded key spec not recognized: failed t
o construct sequence from byte[]: unknown tag 13 encountered
OpenSSL::PKey::RSAError: Neither PUB key nor PRIV key:
from org/jruby/ext/openssl/PKeyRSA.java:309:in `initialize'
from (irb):3:in `<eval>'
from org/jruby/RubyKernel.java:1000:in `eval'
from org/jruby/RubyKernel.java:1298:in `loop'
from org/jruby/RubyKernel.java:1120:in `catch'
from org/jruby/RubyKernel.java:1120:in `catch'
Then i experimenting with private key, i've removed -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- from PEM file, and after this i'm able to execute this on Jruby:
irb(main):005:0> require "base64"
=> true
irb(main):006:0> k = OpenSSL::PKey::RSA.new(Base64.decode64(File.read("private.pem")))
=> #<OpenSSL::PKey::RSA:0x1cff11c>
irb(main):007:0> k.private?
=> true
Is any way to enable Jruby OpenSSL automatically detect PEM file format and load Base64 private keys? This is frustrating public keys in Base64 format opened successfully, private key don't.