BouncyCastle and AES-GCM - java

I'd like to use AES-GCM with BouncyCastle as the provider in order to avail myself of integrity checks using decryption. I'm curious about the kind of exception raised when the integrity check fails. Is it InvalidCipherTextException?
Also are there any other exceptions I should be handling in the context of decrypting an AES-GCM encrypted blob?
I see that there are a few more exceptions listed out at http://www.cs.berkeley.edu/~jonah/bc/org/bouncycastle/crypto/package-tree.html

For the lightweight API, the resulting exception is indeed the InvalidCipherTextException. This answer has been extracted from the Bouncy Castle source code, which is openly available (e.g. using anonymous access to the source repository).
if (!Arrays.constantTimeAreEqual(this.macBlock, msgMac))
{
throw new InvalidCipherTextException("mac check in GCM failed");
}
This seems identical in the 1.13 to 1.18 version of this file in the repository, please check again for later versions.

Related

Bouncy Castle Configuration for TLS

I am using a test app that used java for TLS communication. Standard Oracle java is installed in my system.
I need to use the TLS_DHE_RSA_WITH_AES_128_CCM cipher suite, which is not supported by standard Java, so many suggested using Bouncy Castle. I downloaded and copied the bcprov-ext-jdk18on-171.jar to $JAVA_HOME/lib folder.
Also, updated java.security file to include Bouncy Castle in the provider list as below:
security.provider.4=org.bouncycastle.jce.provider.BouncyCastleProvider
I still cannot get TLS_DHE_RSA_WITH_AES_128_CCM to work though.
Are the steps I did sufficient and correct? Can someone suggest the steps to install and configure Bouncy Castle?
The BouncyCastleProvider adds cryptographic algorithms such as the AES in the CCM mode of operation to the available algorithms of Cipher and other classes. As CCM is not included by default in Java, you will need to register this provider through code (i.e. Security.addProvider(new BouncyCastleProvider)) or adding it into the java.security file (as demonstrated in the question). You will probably want to add it to the end of the provider list as the algorithms of the Oracle provider are generally better tested and may be sped up using hardware acceleration.
However, the BouncyCastleProvider does not contain an implementation of the TLS protocol. You'd need to register the BouncyCastleJsseProvider for that instead. This is required as the Java TLS implementation won't magically know how to use the CCM implementation within Bouncy Castle. JSSE is an acronym of the Java Secure Socket Extension.
You can add that provider at the start of the providers so you know for sure that this provider is used for implementing TLS:
Security.insertProviderAt(new rg.bouncycastle.jsse.provider.BouncyCastleJsseProvider(), 1);
And you can also directly register it in the java.security file.
Note that the JSSE provider doesn't provide implementations such as RSA or AES for Cipher or Signature so it should not be in the way.

JCE cannot authenticate the provider ABA

I have to run a quite old programcode which uses ABA-provider for JCE.
All classes are available in the source folder. However, a NoSuchProviderException occures: "JCE cannot authenticate the provider ABA".
I found some related topics in the forums but they coulnd't help me out.
This is what I did:
ABAProvider prov = new ABAProvider();
Security.addProvider(prov);
In debug-mode prov is initialized but this throws the exception:
keyFactory = SecretKeyFactory.getInstance( "DES", "ABA" );
I hope this information might help you to help me :)
Thanks in advance!
ABA seems to be a cleanroom implementation of Java JCE. Just remove the dependency and use the providers supplied in your favorite runtime
Signing certificates for Java have to be renewed. You cannot use an old certificate on a new version of Java. So the signature on the provider has likely expired.
More information here:
The next step is to request a code-signing certificate so that you can use it to sign your provider prior to testing. The certificate will be good for both testing and production. It will be valid for 5 years.
The usefulness of DES for most cryptographic operations (possibly except creating 3 key TDES) has "expired" as well.

Java-6 to Java-7 Kerberos - breaking behaviour change sessionKey now AP-REQ.Authenticator.subkey

I'm working on a project where we use JAAS/Krb5LoginModule with useTicketCache & doNotPrompt as well as the allowtgtsessionkey registry change to piggy back our authentication on the windows logon of the domain joined computer.
We then use jgss/kerberos to get a GSS API Kerberos Token (rfc1964) which we use to secure a SOAP Message using the WSS Kerberos Token Profile 1.1.1 when communicating with a service. This involves including the b64 encoded GSS Token in the Security element of the SOAP Envelope/Header and using the client/service sessionKey to sign a component of the element.
We are getting the client/sessionKey by querying the private credentials of the javax.security.auth.Subject which the JAAS/Krb5LoginModule returns and looking for a javax.security.auth.kerberos.KerberosTicket which matches our service peer name and invoking its getSessionKey().
All of this works fine in Java-6, however Java-7 clients are failing as there seems to have been a change in the Kerberos KRB_AP_REQ message that Java-7 creates. The Java-7 KRB_AP_REQ Authenticator contains a sub-key which is different to the sessionKey. Since the Kerberos specification (see excerpt below) says that this subkey supersedes the sessionKey then our Java-6 behaviour of using the sessionKey for signing is no longer correct.
RFC1510 - The Kerberos Network Authentication Service (V5)
5.3.2. Authenticators
subkey This field contains the client's choice for an encryption
key which is to be used to protect this specific
application session. Unless an application specifies
otherwise, if this field is left out the session key from
the ticket will be used.
I've not seen anywhere where this change is documented but have confirmed the behaviour at least in Java(TM) SE Runtime Environment (build 1.7.0_11-b21).
At this point unless I have missed something glaringly obvious (and I hope I have), our options seem to be:
Change the Java-7 Kerberos Configuration to revert to Java-6 behaviour - unfortunately I've not seen anything in the docs that seems to suggest that this is possible.
Find a way to get access to the subkey. For this options I have explored are
a. Decode the b64 encoded GSS Token, pull out the encrypted Authenticator, decrypt it using the sessionKey, decode the ASN.1 DER encoding and pull out the subkey.
b. Use what appears to be non-standard GSS API Extensions and use the ExtendedGSSContext.inquireSecContext() method with KRB5_GET_SESSION_KEY to get at the subKey.
Any suggestions/insight in to these or other possible options?
We also experience this issue when using JGSS Api in Java 1.7 to obtain the client's session key. Apparently, in Java 1.6 the sub-key was always cloned from the session key, see the sun.security.krb5.EncryptionKey constructor:
EncryptionKey(EncryptionKey encryptionkey)
throws KrbCryptoException
{
keyValue = (byte[])(byte[])encryptionkey.keyValue.clone();
keyType = encryptionkey.keyType;
}
Starting from Java 1.7.0_b07, this constructor utilizes java.security.SecureRandom to generate a new subkey. I think this has been done as part of JDK-4460771 : Kerberos should be able to generate sub-session keys. It seems that the com.sun.security.jgss.ExtendedGSSContext provides the "standard" way to access the subkey from now on (on Sun JVMs), so I guess we should use this class if it is available (on the underlying JVM), see:
JDK-6710360 : export Kerberos session key to applications
Thanks,
Detelin
I don't see anything in the ExtendedGSSContext.inquireSecContext() doc to indicate that it returns the subkey if present for KRB5_GET_SESSION_KEY; do you know from some other source that it does?
In any case, using the subkey is what you need to do. I would look at it this way: your original implementation was not correct, because the WSS Kerberos doc clearly states that the subkey is to be used if present. It just happened to work because the Java 6 Kerberos library did not generate a subkey. Now that one has appeared your bug is revealed, and you have to fix it.
I'm not familiar with WSS, but the doc seems to indicate that you can choose various encodings for the token, and one is to use GSSAPI instead of a Kerberos AP-REQ directly. Perhaps if you had used GSSAPI to begin with, it would have insulated you from this change -- and perhaps switching to it now would be the easiest fix.

addProvider bouncycastle filenotfoundexception

I have been able to run decryption and encryption locally using the bouncycastle jars. I have generated keys that I want to put the public key a client (Java and Android) and the private key in a web service. I have been able to encrypt and encoded a message and send the encrypted message to the webservice (on a hosted service by Lunarpages), but the webservice decryption fails with a FileNotFoundException on the line
BouncyCastleProvider bc = new BouncyCastleProvider();
or
Security.addProvider(new BouncyCastleProvider());
The bcprov-ext-jdk14-146.jar and the bcprov-jdk14-146.jar is included in the web-inf lib directory.
Is there something I can do programmatic to enable this or does Lunarpages have to do something?
I couldnt even get a stacktrace to print for me and so I thought I might attempt a different provider to see if I get a better response - the SunJCE.
access denied (java.security.SecurityPermission insertProvider.SunJCE)
java.security.AccessControlContext.checkPermission(AccessControlContext.java:269)
java.security.AccessController.checkPermission(AccessController.java:401)
java.lang.SecurityManager.checkPermission(SecurityManager.java:524)
java.lang.SecurityManager.checkSecurityAccess(SecurityManager.java:1673)
java.security.Security.check(Security.java:1307)
java.security.Security.insertProviderAt(Security.java:697)
java.security.Security.addProvider(Security.java:757)
net.wpstudios.tcws.pgp.RSAEncrypt.generateKeys(RSAEncrypt.java:81)
javax.servlet.http.HttpServlet.service(HttpServlet.java:165)
javax.servlet.http.HttpServlet.service(HttpServlet.java:103)
com.caucho.server.http.FilterChainServlet.doFilter(FilterChainServlet.java:96)
com.caucho.server.http.Invocation.service(Invocation.java:315)
com.caucho.server.http.CacheInvocation.service(CacheInvocation.java:135)
com.caucho.server.http.RunnerRequest.handleRequest(RunnerRequest.java:346)
com.caucho.server.http.RunnerRequest.handleConnection(RunnerRequest.java:274)
com.caucho.server.TcpConnection.run(TcpConnection.java:139)
java.lang.Thread.run(Thread.java:534)
Does the FileNotFound exception matter? Obviously the caucho server setup is using access restrictions on adding providers. Never mind that, if you want to develop some application level encryption/decryption you can simply use the bouncy castle crypto API directly. It's not as friendly as the JCE but it is useable enough. This might not work if you want to use a library that in its turn uses the JCA/JCE framework though.
Lunarpages is to change the permissions or add providers manually (using resin.conf, it seems), but it might be hard to change them just for you, unless you are the only one using the Java application server. It never hurts to ask I suppose.

how can i use encryption algorithm from installed provider on J9 vm?

Hi
I am trying to user RSA on J9. The algorithm is offered by the 'J9JCE' provider which is an installed extension(i listed all the existing providers and algorithms and found them) but the exception i get is:
Exception in thread "main" java.security.NoSuchAlgorithmException: JCE provider signer certificates not found/read
at javax.crypto.Cipher.getInstance(Cipher.java:191)
at Test.encript(Test.java:26)
at Test.main(Test.java:42)
I still don't know the answer to the problem but a workaround is to use the provider from Bouncy Castle which works fine.

Categories