Using PKCS11 with JCE means that you can use HSMs to house your private keys, which protects them from theft or misappropriation. And that's a very good thing.
With JCE, you use instances of subclasses of Key to perform cryptographic operations. Keys can be PublicKey, PrivateKey or SecretKey objects. SecretKey objects represent keys to use with a symmetric algorithm, like AES. PublicKey and PrivateKey objects comprise a key pair used for asymmetric algorithms, like RSA.
What PKCS11 does is replace SecretKey and PrivateKey objects with sham objects that represent index numbers into the HSM. When you ask JCE to perform a cryptographic operation with those keys, it instead actually delegates the task to the HSM. The HSM will look up the keys, use them internally, and return the result to you. When done that way, the secret material never leaves the HSM.
But what happens when you have to manage potentially thousands of keys? That's too many to store in the limited storage space of an HSM, and having the HSM root through its storage to find the key you want isn't what it was designed best to do.
No, instead you should use a database to store all of the keys. But the problem is that the database isn't cryptographically protected the same way an HSM is.
The solution is in the Cipher class wrap() and unwrap() methods.
What you do is you establish a SecretKey in your HSM. Give it an alias of "WrappingKey" or something of that sort. If you ask your HSM to generate such a key internally, then it will never be allowed to leave the HSM. That's a good thing. You then generate whatever keys you need and use the Cipher wrap() method to turn the private key material into an encrypted byte array. You can write that byte array to the database with confidence, since there's no use you can make of that byte array without the secret key that was used to encrypt it, which is safely encased in the HSM.
Now what if you want to use it?
You fetch the bytes from the database again and use the same Cipher object to unwrap the key. What you'll get is a PrivateKey. But as we've seen, PrivateKeys that you get from an HSM are just sham objects. You don't actually get to see that PrivateKey - it is merely a reference to the key in the HSM. You then can use the HSM to perform whatever crypto operation you need to do on that key. The HSM doesn't permanently store the unwrapped key - as soon as the sham object gets dereferenced, the PKCS11 module will tell the HSM to throw it away. But done in this way, the unencrypted form of the private key never leaves the HSM, nor does the encryption key that wraps and unwraps it. Your database can be used to keep track of the potentially millions of private keys you need to keep track of, but no human eyes will ever get to see even one of them.
Showing posts with label java. Show all posts
Showing posts with label java. Show all posts
Thursday, August 26, 2010
Sunday, March 21, 2010
Fancy or ugly Spring wiring? po-TAY-to, po-TAH-to...
One situation we have run across at work is the need to be able to, at configuration, time, choose between two alternate ways to construct an object, depending on the runtime configuration. In a lot of cases, this sort of thing winds up being a datasource configured within the container, meaning that you can use JNDI to your advantage, but this case wasn't really amenable to that.
So once you've split your application context into three pieces (the main piece and each alternative piece), then what?
Spring presently doesn't have any sort of conditionals for application contexts. It does have an <import> statement. You can use property placeholder syntax to conditionalize the import, thusly:
And that works, as long as the whichOne property is a system property. But what if you're using PropertyPlaceholderConfigurer to get placeholder material from a property file? That won't work on <import> tags, because imports take place before bean creation, which is where the configurer gets loaded.
The workaround for that, it turns out, is to rephrase your <import> like this:
That is, create a ClassPathXmlApplicatioContext object out of the correct context file, then call getBean("myChoiceBean") on it, and cache the resulting bean in this context as "myChoiceBean".
So once you've split your application context into three pieces (the main piece and each alternative piece), then what?
Spring presently doesn't have any sort of conditionals for application contexts. It does have an <import> statement. You can use property placeholder syntax to conditionalize the import, thusly:
<import resource="${whichOne}ChoiceContext.xml"/>
And that works, as long as the whichOne property is a system property. But what if you're using PropertyPlaceholderConfigurer to get placeholder material from a property file? That won't work on <import> tags, because imports take place before bean creation, which is where the configurer gets loaded.
The workaround for that, it turns out, is to rephrase your <import> like this:
<bean id="myChoiceBeanFactory" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg type="java.lang.String" value="${whichOne}ChoiceContext.xml"/>
</bean>
<bean factory-bean="myChoiceBeanFactory" factory-method="getBean">
<constructor-arg value="myChoiceBean"/>
</bean>
That is, create a ClassPathXmlApplicatioContext object out of the correct context file, then call getBean("myChoiceBean") on it, and cache the resulting bean in this context as "myChoiceBean".
Labels:
java
Monday, March 8, 2010
Spring JCE / PKCS11
At work we have a need to integrate JCE with network crypto boxes. Turns out, with Spring, it's almost completely trivial.
If you're going to be using either a smart card or a network crypto provider, what you're likely to wind up with is a PKCS11 module for your platform. Sun provides for JCE a PKCS11 JCE Provider shim.
First, there is a very handy Spring idiom for adding providers to JCE at runtime. Here's how you can load BouncyCastle, for example, in a Spring application context as a throw-away bean (from this post at the SpringSource forums):
You can add the PKCS11 provider in almost exactly the same way. The only change is how you declare the actual provider bean within the <list>:
The PKCS11ConfigFactoryBean's job is to spit out an InputStream, which it creates from a mock configuration file that it creates from various properties. You can check the PKCS11 provider's documentation for the complete list of the contents of the config file, but at the very least, it has to contain a line that says "library=path/to/pkcs11/module". After filling a
Once you have the provider, you'll want to obtain a keystore. Your actual working code should be in the form of a bean that has a java.security.KeyStore property. You'll use the KeyStore to obtain the certificates and keys that are stored in the hardware. Spring provides the KeyStoreFactoryBean to fetch, load and initialize the keystore and plug it into your code. Just specify that you want a type "PKCS11" keystore and use the PIN as the password. You can then look up the certs and private keys and use them as normal. Of course, the
If you're going to be using either a smart card or a network crypto provider, what you're likely to wind up with is a PKCS11 module for your platform. Sun provides for JCE a PKCS11 JCE Provider shim.
First, there is a very handy Spring idiom for adding providers to JCE at runtime. Here's how you can load BouncyCastle, for example, in a Spring application context as a throw-away bean (from this post at the SpringSource forums):
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="staticMethod" value="java.security.Security.addProvider"/>
<property name="arguments">
<list>
<bean class="org.bouncycastle.jce.provider.BouncyCastleProvider"/>
</list>
</property>
</bean>
You can add the PKCS11 provider in almost exactly the same way. The only change is how you declare the actual provider bean within the <list>:
<bean class="sun.security.pkcs11.SunPKCS11">
<constructor-arg>
<bean class="PKCS11ConfigFactoryBean">
<property name="modulePath" value="path/to/pkcs11/module"/>
</bean>
</constructor-arg>
</bean>
The PKCS11ConfigFactoryBean's job is to spit out an InputStream, which it creates from a mock configuration file that it creates from various properties. You can check the PKCS11 provider's documentation for the complete list of the contents of the config file, but at the very least, it has to contain a line that says "library=path/to/pkcs11/module". After filling a
StringBuffer
with the configuration options (don't forget to separate each line with \n), the getObject() method should return new ByteArrayInputStream(string.toBytes())
.Once you have the provider, you'll want to obtain a keystore. Your actual working code should be in the form of a bean that has a java.security.KeyStore property. You'll use the KeyStore to obtain the certificates and keys that are stored in the hardware. Spring provides the KeyStoreFactoryBean to fetch, load and initialize the keystore and plug it into your code. Just specify that you want a type "PKCS11" keystore and use the PIN as the password. You can then look up the certs and private keys and use them as normal. Of course, the
PrivateKey
object you get back won't actually be the key - calling getEncoded()
on it, for example, won't work - it'll just be a sham object that provides a pointer to the actual key when it comes time to use it.
Labels:
java
Monday, February 22, 2010
Import private key into java keystore - an easier way
If you ask google how you import a private key into a Java keystore file, the answers you get back all have source code for opening a DER file, reading it in and writing a keystore file programatically.
That works, but I've discovered a much, much easier way.
The -storetype argument to keytool allows you to translate key material. In fact, jarsigner can take the argument
If you can make a pkcs12 file with your private key and certificate - which should be easy with openssl's pkcs12 command - then you can use the following command to turn that into a java keystore:
That works, but I've discovered a much, much easier way.
The -storetype argument to keytool allows you to translate key material. In fact, jarsigner can take the argument
-storetype pkcs12
, meaning you don't need to keep your signing key in a JCE keystore at all. But I digress.If you can make a pkcs12 file with your private key and certificate - which should be easy with openssl's pkcs12 command - then you can use the following command to turn that into a java keystore:
keytool -importkeystore -srckeystore file.p12 -srcstoretype pkcs12 -destkeystore file.jceks -deststoretype JCEKS
Labels:
java,
technology
Thursday, September 3, 2009
Java and the Impossible Generic List
Since Java 1.5, I've been used to writing List<Class>, allowing the compiler to insure type safety of collections.
There's one issue with this, however.
let's say you have an interface. We'll call it TheInterface.
Java is more than content with allowing you to say List<TheInterface>
So what?
The problem with that syntax is that it says that the contents of the List will always be items whose exact type is TheInterface.
But it's an interface. So there will never be any of those.
Stupid Java.
The solution is simple: you're supposed to say List<? extends TheInterface>. This lets the list contain any objects that implement the given interface, which is almost assuredly exactly what you want.
So why isn't List<TheInterface> a compile error?
Bueller?
There's one issue with this, however.
let's say you have an interface. We'll call it TheInterface.
Java is more than content with allowing you to say List<TheInterface>
So what?
The problem with that syntax is that it says that the contents of the List will always be items whose exact type is TheInterface.
But it's an interface. So there will never be any of those.
Stupid Java.
The solution is simple: you're supposed to say List<? extends TheInterface>. This lets the list contain any objects that implement the given interface, which is almost assuredly exactly what you want.
So why isn't List<TheInterface> a compile error?
Bueller?
Labels:
java
Thursday, April 2, 2009
Gzipped JMS message bodies
If you want to send large messages with JMS, it is probably a good idea to compress them, assuming they contain data that's compressible (particularly effective with XML payloads). This is a natural fit for JMS BytesMessages, and compression is easily done with GZIPInputStream and GZIPOutputStream.
When I first did this, I used ByteArrayInputStream/ByteArrayOutputStream as the stream feeding the GZIP stream, but the problem with that is that you have to copy the underlying byte array into or out of the message in its entirety. This represents an extra buffer copy that in principle is not necesary. BytesMessage provides byte buffer I/O. Unfortunately, it doesn't conform to the InputStream / OutputStream interface directly.
So the fix is to shim BytesMessages using what I call BytesMessageInputStream and BytesMessageOutputStream. Once you shim the BytesMessage to a stream, you simply use that stream in the constructor of a GZIP stream and you're ready to go. Once the data has been written to the GZIP stream and that stream closed, the message can be sent or acknowledged, depending on which direction you're going.
When I first did this, I used ByteArrayInputStream/ByteArrayOutputStream as the stream feeding the GZIP stream, but the problem with that is that you have to copy the underlying byte array into or out of the message in its entirety. This represents an extra buffer copy that in principle is not necesary. BytesMessage provides byte buffer I/O. Unfortunately, it doesn't conform to the InputStream / OutputStream interface directly.
So the fix is to shim BytesMessages using what I call BytesMessageInputStream and BytesMessageOutputStream. Once you shim the BytesMessage to a stream, you simply use that stream in the constructor of a GZIP stream and you're ready to go. Once the data has been written to the GZIP stream and that stream closed, the message can be sent or acknowledged, depending on which direction you're going.
public class BytesMessageInputStream extends InputStream {
private final BytesMessage message;
public BytesMessageInputStream(BytesMessage bm) { this.message = bm; }
public boolean markSupported() { return false; }
public int read() throws IOException {
try {
return this.message.read();
}
catch(MessageEOFException ex) { return -1; }
catch(JMSException ex) { throw new IOException(ex); }
}
public int read(byte[] buf) throws IOException {
try {
return this.message.readBytes(buf);
}
catch(JMSException ex) { throw new IOException(ex); }
}
}
public class BytesMessageOutputStream extends OutputStream {
private final BytesMessage message;
public BytesMessageOutputStream(BytesMessage bm) { this.message = bm; }
public void write(byte b) throws IOException {
try {
this.message.writeByte(b);
}
catch(JMSException ex) { throw new IOException(ex); }
}
public void write(byte[] buf) throws IOException {
try {
this.message.writeBytes(buf);
}
catch(JMSException ex) { throw new IOException(ex); }
}
public void write(byte[] buf, int off, int len) throws IOException {
try {
this.message.writeBytes(buf, off, len);
}
catch(JMSException ex) { throw new IOException(ex); }
}
}
Labels:
java
Wednesday, April 1, 2009
java NVL function
NVL is a function in Oracle PL/SQL that is more or less this:
And that's all well and good. The only problem occurs when the value of
But wouldn't it be easier to read as
Well, nvl() is easy to write, except that Java wants the arguments to be strongly typed.
Or does it?
You can declare the arguments are return as Object, but then you have to cast the return, and the compiler will not protect you from type mismatches.
The solution is generics. Write nvl like this:
Mischief managed. The compiler will guarantee that there can be no type clashes, and so long as the same type is used for the two args and return, you're good to go.
NVL(a,b) ==> (a == null)?b:a
And that's all well and good. The only problem occurs when the value of
a
either has side effects or either a or b are long and complex. You could write
foo a = ... long complicated code with possible side effects ...
foo b = ...yadda yadda yadda...
a = (a==null)?b:a;
But wouldn't it be easier to read as
a=nvl(... long complicated code with possible side effects ..., ... yadda yadda yadda ...)
?Well, nvl() is easy to write, except that Java wants the arguments to be strongly typed.
Or does it?
You can declare the arguments are return as Object, but then you have to cast the return, and the compiler will not protect you from type mismatches.
The solution is generics. Write nvl like this:
public <T> T nvl(T a, T b) {
return (a == null)?b:a;
}
Mischief managed. The compiler will guarantee that there can be no type clashes, and so long as the same type is used for the two args and return, you're good to go.
Labels:
java
Wednesday, December 17, 2008
JBoss and custom LoginModules for data sources
This is rather a specialized topic, but precious little has been said about it, so I figure it's worth a mention.
A data source in JBoss is typically either a JMS or JDBC connection pool, more or less. It represents a resource within JBoss that you can turn to to obtain the thing you want, use it, then throw it away (typically the connections are wrapped with code that catches the "close()" call and rather than closing the connection returns it to the available pool).
If the resource represents a database or remote JMS server, you're going to need to authenticate - typically by providing a username and password. In most enterprise situations, you don't want those passwords to be in plaintext in the configuration files. Rather, you have either some sort of configurable password encryption system or a password fetching system. In every shop I've worked in so far where this has been an issue, there's been a pre-existing mechanism that is set in concrete and must be used more or less without modification to obtain passwords to connect to enterprise resources.
Well, if you're configuring a data source within JBoss, you give that data source an <application-and-security-domain>, which is a <application-policy> node within server/___/conf/login-config.xml, which contains a <authentication> section which provides the username and password. The question is, how can you provide the bridge between JBoss and your established mechanism for providing username and password? Naively, the answer is that you must write your own custom JAAS login module.
Fortunately, there is a much easier way.
JBoss provides a ConfiguredIdentityLoginModule, which is simply a wrapper for a plaintext username and password. The simplest way to wire in your own password fetching code is to extend this module. You simply need to replace this method in the class:
The "options" map is a map of the list of module-options from login-config.xml. You simply call super.initialize() with all of the same arguments, but with a different options map. The new options map will have in it the "username" and plaintext "password" options that are required by the ConfiguredIdentityLoginModule.
For example, if you have a CryptoWidget that can decrypt passwords, you'd write something like this:
And that, more or less, is the entire class. You can do anything you need to modify the options map, so long as the options map you pass in to super.initialize() is what the superclass expects to get. It might be a good idea to remove any options that you require that the superclass does not require. For instance, if a "salt" option was required to pass some additional argument into the CryptoWidget, you'd fetch it, then remove it from newOptions.
Incidentally, it is necessary to make a copy of the options map because it is an unmodifiable map (note that we make newOptions unmodifiable before calling super.initialize() also).
A data source in JBoss is typically either a JMS or JDBC connection pool, more or less. It represents a resource within JBoss that you can turn to to obtain the thing you want, use it, then throw it away (typically the connections are wrapped with code that catches the "close()" call and rather than closing the connection returns it to the available pool).
If the resource represents a database or remote JMS server, you're going to need to authenticate - typically by providing a username and password. In most enterprise situations, you don't want those passwords to be in plaintext in the configuration files. Rather, you have either some sort of configurable password encryption system or a password fetching system. In every shop I've worked in so far where this has been an issue, there's been a pre-existing mechanism that is set in concrete and must be used more or less without modification to obtain passwords to connect to enterprise resources.
Well, if you're configuring a data source within JBoss, you give that data source an <application-and-security-domain>, which is a <application-policy> node within server/___/conf/login-config.xml, which contains a <authentication> section which provides the username and password. The question is, how can you provide the bridge between JBoss and your established mechanism for providing username and password? Naively, the answer is that you must write your own custom JAAS login module.
Fortunately, there is a much easier way.
JBoss provides a ConfiguredIdentityLoginModule, which is simply a wrapper for a plaintext username and password. The simplest way to wire in your own password fetching code is to extend this module. You simply need to replace this method in the class:
public void initialize(Subject subject, CallbackHandler handler, Map sharedState, Map options)
The "options" map is a map of the list of module-options from login-config.xml. You simply call super.initialize() with all of the same arguments, but with a different options map. The new options map will have in it the "username" and plaintext "password" options that are required by the ConfiguredIdentityLoginModule.
For example, if you have a CryptoWidget that can decrypt passwords, you'd write something like this:
public void initialize(Subject subject, CallbackHandler handler, Map sharedState, Map options) {
Map newOptions = new HashMap(options);
String pw = (String) newOptions.get("password");
pw = CryptoWidget.decrypt(pw);
newOptions.put("password", pw);
newOptions = Collections.unmodifiableMap(newOptions);
super.initialize(subject, handler, sharedState, options);
}
And that, more or less, is the entire class. You can do anything you need to modify the options map, so long as the options map you pass in to super.initialize() is what the superclass expects to get. It might be a good idea to remove any options that you require that the superclass does not require. For instance, if a "salt" option was required to pass some additional argument into the CryptoWidget, you'd fetch it, then remove it from newOptions.
Incidentally, it is necessary to make a copy of the options map because it is an unmodifiable map (note that we make newOptions unmodifiable before calling super.initialize() also).
Labels:
java
Subscribe to:
Posts (Atom)