The DESKey.getKey(byte[], short) method definitely is one of the most controversial methods of the Java Card 2.1 API. This method is quite simple; as stated in its description, it “Returns the Key data in plain text”. This definition is of course a nightmare for smart card security people: not only does it access the value of a cryptographic key, but it also copies this value in plaintext in a plain old buffer. When you apply for a Common Criteria certification, this method does not look good.
On top of it, DES keys are not the only ones on which this applies. All key types have their getters, all copying plaintext values. With Bandol, we have an opportunity to deprecate all these dreaded method calls. Now, should we?
Let’s start by a little bit of background about this method. it actually originates in the Java interface java.security.Key, which includes a getEncoded method that returns the value of the key as a string, with some kind of encoding. By default, this encoding is not encrypted, and this is how the method became getKey in Java Card. However, this method offers something interesting, as its definition states that it may return “null, if the key does not support encoding”. The idea of not supporting encoding is not completely clear, but it sure is a tempting option for Java Card.
Now, about deprecation. Deprecation litterally means “strongly disapproved of”, which should be enough of a warning not to use a feature. In Java, the word is formally defined as a VM attribute for elements that may be deprecated. The effect of deprecation is that it warns developers not to use a feature (the compiler actually displays a warning), while allowing the feature to be used for backward compatibility. A deprecated feature may then be removed in later releases of the specification.
Now, we can get back to our original topic: should we deprecate the getter on key objects? Although this originally sounds like a good idea, the answer is not as obvious, for several reasons:
- The API is actually used in today’s applications, which means that deprecating would not remove it from the implementations anytime soon. It may even never be removed, as other eprecated features. Since this method is dangerous just by being around, security is not improved.
- The API is not completely useless. There exist some key diversification algorithms in which computations are performed on the actual values of keys. This is just wrong, but the applications that use them are deployed, and retiring them is not easy.
- Key values are supposed to be protected: in many cases, some guarantees are provided on both their integrity and confidentiality. Some applications have therefore used key objects as containers for sensitive data. And of course, these applications heavily use the getters. If the key objects are removed, developers may right fully ask for a secure data container (with a getter).
These three arguments, put together, make a fairly strong case against deprecation. However, alternative solutions are possible. One of them would be to enrich the cryptographic key factory with an optional boolean argument that would indicate whether or not this particular key should support a getter. And of course, if it does not support it, the getter methods can simply throw an exception. With a proper implementation, this simple change could bring a simple and efficient solution to that problem.
No Comments