XML digital signature (Xades) with JRuby

Good morning,

I am trying to use the Java's Xades signature with JRuby in my Ruby on Rails application. But since two days now, i am facing the following errors without getting any response to solve them.

This is the corresponding java code from this page:

Load the KeyStore and get the signing key and certificate. KeyStore ks = KeyStore.getInstance("JKS"); ks.load(new FileInputStream("mykeystore.jks"), "changeit".toCharArray()); KeyStore.PrivateKeyEntry keyEntry =     (KeyStore.PrivateKeyEntry) ks.getEntry         ("mykey", new KeyStore.PasswordProtection("changeit".toCharArray())); X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

// Create the KeyInfo containing the X509Data. KeyInfoFactory kif = fac.getKeyInfoFactory(); List x509Content = new ArrayList(); x509Content.add(cert.getSubjectX500Principal().getName()); x509Content.add(cert); X509Data xd = kif.newX509Data(x509Content); KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

My corresponding JRuby code is the following:

require 'java'

include_class 'java.lang.System' include_class 'java.lang.Object' include_class('java.lang.String'){|package,name| "J#{name}"} include_class 'java.io.IOException' include_class 'java.io.InputStream' include_class 'java.io.FileOutputStream' include_class 'java.io.FileInputStream' include_class 'java.security.KeyStore' include_class 'java.security.KeyStoreException'

password = JString.new("changeit") ks = KeyStore.getInstance("JKS") ks.load(FileInputStream.new("keys/keystoreCps.jks"), password.toCharArray())

keyEntry = KeyStore.PrivateKeyEntry.new keyEntry = ks.getEntry("mykey", KeyStore.PasswordProtection.new(password.toCharArray())) cert = keyEntry.getCertificate()

#Create the KeyInfo containing the X509Data. kif = sigFactory.getKeyInfoFactory() x509Content = ArrayList.new x509Content.add(cert.getSubjectX500Principal().getName()) x509Content.add(cert) xd = kif.newX509Data(x509Content) ki = kif.newKeyInfo(Collections.singletonList(xd))

So i am getting these errors with these 2 lines: keyEntry = KeyStore.PrivateKeyEntry.new keyEntry = ks.getEntry("mykey", KeyStore.PasswordProtection.new(password.toCharArray())):

1) NoMethodError: undefined method `PrivateKeyEntry' for Java::JavaSecurity::KeyStore:Class 2) undefined method `PasswordProtection' for Java::JavaSecurity::KeyStore:Class

I have visited this javadoc site, but still don't know how to solve those problems

Kindly help me solve these errors. Thanks in advance for your responses

Regards,

Good morning,

I am trying to use the Java's Xades signature with JRuby in my Ruby on Rails application. But since two days now, i am facing the following errors without getting any response to solve them.

This is the corresponding java code from this page: Oracle Java Technologies | Oracle

Load the KeyStore and get the signing key and certificate. KeyStore ks = KeyStore.getInstance("JKS"); ks.load(new FileInputStream("mykeystore.jks"), "changeit".toCharArray()); KeyStore.PrivateKeyEntry keyEntry = (KeyStore.PrivateKeyEntry) ks.getEntry ("mykey", new KeyStore.PasswordProtection("changeit".toCharArray())); X509Certificate cert = (X509Certificate) keyEntry.getCertificate();

// Create the KeyInfo containing the X509Data. KeyInfoFactory kif = fac.getKeyInfoFactory(); List x509Content = new ArrayList(); x509Content.add(cert.getSubjectX500Principal().getName()); x509Content.add(cert); X509Data xd = kif.newX509Data(x509Content); KeyInfo ki = kif.newKeyInfo(Collections.singletonList(xd));

My corresponding JRuby code is the following:

require 'java'

include_class 'java.lang.System' include_class 'java.lang.Object' include_class('java.lang.String'){|package,name| "J#{name}"} include_class 'java.io.IOException' include_class 'java.io.InputStream' include_class 'java.io.FileOutputStream' include_class 'java.io.FileInputStream' include_class 'java.security.KeyStore' include_class 'java.security.KeyStoreException'

password = JString.new("changeit") ks = KeyStore.getInstance("JKS") ks.load(FileInputStream.new("keys/keystoreCps.jks"), password.toCharArray())

keyEntry = KeyStore.PrivateKeyEntry.new

I don't really know what I am talking about here, but that line tries to call method PrivateKeyEntry on class KeyStore. Is PrivateKeyEntry not in fact a class? Should it be KeyStore::PrivateKeyEntry or something along those lines?

Colin

I don't really know what I am talking about here, but that line tries to call method PrivateKeyEntry on class KeyStore. Is PrivateKeyEntry not in fact a class? Should it be KeyStore::PrivateKeyEntry or something along those lines?

Colin

HI, Thanks for your answer. KeyStore.PrivateKeyEntry is a java static class: http://docs.oracle.com/javase/1.5.0/docs/api/java/security/KeyStore.PrivateKeyEntry.html

Still getting the same error gsaly

What? You get exactly the same error if you replace the . with ::

The question is what is the right syntax in jruby for referencing that class? I don't know the answer to that question, but I think that may be where the problem lies.

Colin

Thank you fro your help.

I ve used the :: unless of . and it seem to work so i have the following lines now:

password = JString.new("changeit") ks = KeyStore.getInstance("JKS") ks.load(FileInputStream.new("keys/keystoreCps.jks"), password.toCharArray()) keyEntry = ks.getEntry("mykey", KeyStore::PasswordProtection.new(password.toCharArray())) cert = keyEntry.getCertificate

Then i am now getting the following error for the last line: "NoMethodError: undefined method `getCertificate' for nil:NilClass"

Then i tried cert = X509Certificate.new cert = keyEntry.getCertificate Then i am getting the following error:" TypeError: no public constructors for Java::JavaSecurityCert::X509Certificate"

Thanks

Thank you fro your help.

I ve used the :: unless of . and it seem to work so i have the following lines now:

password = JString.new("changeit") ks = KeyStore.getInstance("JKS") ks.load(FileInputStream.new("keys/keystoreCps.jks"), password.toCharArray()) keyEntry = ks.getEntry("mykey", KeyStore::PasswordProtection.new(password.toCharArray())) cert = keyEntry.getCertificate

Then i am now getting the following error for the last line: "NoMethodError: undefined method `getCertificate' for nil:NilClass"

That means that keyEntry is nil, so presumably your getEntry call failed.

Then i tried cert = X509Certificate.new cert = keyEntry.getCertificate Then i am getting the following error:" TypeError: no public constructors for Java::JavaSecurityCert::X509Certificate"

Well that error is pretty self explanatory. But that line is not achieving anything anyway as you are immediately overwriting cert with something else.

Colin

Well that error is pretty self explanatory. But that line is not achieving anything anyway as you are immediately overwriting cert with something else.

Colin

The complete code is now:

ks = KeyStore.getInstance("JKS") charsPass = "changeit".to_java_string.toCharArray ks.load(FileInputStream.new("keys/truststore.jks"), charsPass) keyEntry = ks.getEntry("mykey", KeyStore::PasswordProtection.new(charsPass)) cert = keyEntry.getCertificate

#Create the KeyInfo containing the X509Data. kif = sigFactory.getKeyInfoFactory x509Content = ArrayList.new x509Content.add(cert.getSubjectX500Principal.getName) x509Content.add(cert) xd = kif.newX509Data(x509Content) ki = kif.newKeyInfo(Collections.singletonList(xd))

But i am getting "NoMethodError: undefined method `getCertificate' for nil:NilClass" error for this line: cert = keyEntry.getCertificate

Am i missing something? do you know for which reason my getEntry call failed ? because i am doing exactly the same...

Thanks