Re: How to get the plaintext of a Secret Key Entry in Mozilla NSSDB PKCS11?

Robert Relyea <[email protected]> Mon, 18 Oct 2021 10:06:06 -0700
Newsgroups gmane.comp.mozilla.crypto
Message-ID <[email protected]>
On 10/14/21 12:25 PM, AZ19AGENT Minecraft wrote:
>
> I have a mozilla NSSDB PKCS11, it includes one of three things. 
> Certificates, keys, and SecretKeyEntry. I would like to know the 
> content of a SecretKeyEntry with the alias "StoreXKey". Firstly, is 
> extracting the plaintext of a SecretKeyEntry possible? I seem to think 
> so because of links: 
> https://technosock.blogspot.com/2007/12/token-knowledge.html 
> <https://technosock.blogspot.com/2007/12/token-knowledge.html> and 
> https://docs.oracle.com/javase/8/docs/api/java/security/KeyStore.SecretKeyEntry.html#getSecretKey 
> <https://docs.oracle.com/javase/8/docs/api/java/security/KeyStore.SecretKeyEntry.html#getSecretKey>
>

The answer is: "sort of, it's discouraged." In general NSS avoids giving 
application access to any cryptographically sensitive value. These 
include, secret keys, private keys, and internal RNG states. NSS does 
allow these things to be exported when wrapped with another secret key, 
so the application can transport and store these values, but not examine 
them.

The reason for this is two fold: 1) NSS is trying to preserve semantics 
between it's software key store and various hardware cryptographic 
token. The idea is we want NSS application to work with hardware tokens 
by just 'dropping it in' without extra work in the application. 2) when 
operating in FIPS mode, NSS manages all the FIPS requirements on the 
lifecycle (including the need to clear) this sensitive data. 3) Usually 
applications don't actually need to extract a key. I always ask the 
question, "Why do you need this?". In all the time I've worked on NSS 
(decades), I've only had 2 legitimate cases where it was necessary (one 
was key exchange with the kernel, the other was the key wasn't really a 
key, but a hash and NSS didn't provide an interface to access the hash 
as a hash). If this is a key exchange issue (you need to put the key in 
another provider), then I would suggest using a keyExchange algorithm 
and move the key encrypted between the two providers.

Preliminaries done, NSS provides a way to access secret keys using 
PK11_GetKeyData(). This function may return NULL if you are using a 
hardware token, or your NSS token is in FIPS mode. There are tricks to 
get around this, but it looks like you aren't using NSS directly, but 
trying to access softoken through the Jave Sun PKCS11 provider....

> First link gives a way to do it ( which doesn't work for me ) the 
> second link gives us a few methods, namely .getEncoded() which can 
> supposedly be called on a SecretKeyEntry to get the byte array 
> information.
>
> Here is my code thus far, all results hit a null pointer exception 
> when using the getEncoded message. I am sure the SecretKeyEntry exists 
> in the NSSDB.
>
> String configFile = "config.cfg";
> Provider provider = Security.getProvider("SunPKCS11"); // I am 
> confused on how to incorporate the config file as well.
> /* provider = provider.configure(configFile); // Does not work */ 
> Security.addProvider(provider);
Softoken isn't a regular PKCS #11 module, it must be configured with the 
directory where NSS stores it key and cert database. I believe Sun Java 
knows how do this, but I don't know how that works since I don't use 
Java providers to access NSS... Anyway the fact you are failing here, 
probably means you aren't actually getting the NSS database.
> String defaultPIN = "--.--.--.--.----.-...-.--";
> try{
>   KeyStore ks = KeyStore.getInstance("PKCS11");
>   ks.load(null, defaultPIN.toCharArray());
>   KeyStore.SecretKeyEntry skEntry = (KeyStore.SecretKeyEntry)
>   ks.getEntry("StoreXKey",null); // Do I need a password protector here?
>   System.out.println(new String(skEntry.getSecretKey().getEncoded())); 
> <-- Error is thrown here.

If you are in FIPS mode, even with the Java PKCS11 provider properly 
initialized, This will likely fail because Java won't be able to access 
the secretKey directly, so getEncoded() will never work.

Again, I ask: what do you need the plaintext key for?


bob

>  }catch (Exception e){ e.printStackTrace(); }
>
> Any help / advice or links are appreciated.
>
> -- 
> You received this message because you are subscribed to the Google 
> Groups "[email protected]" group.
> To unsubscribe from this group and stop receiving emails from it, send 
> an email to [email protected] 
> <mailto:[email protected]>.
> To view this discussion on the web visit 
> https://groups.google.com/a/mozilla.org/d/msgid/dev-tech-crypto/ee327174-46a8-4392-a3a5-8fdf76b3c984n%40mozilla.org 
> <https://groups.google.com/a/mozilla.org/d/msgid/dev-tech-crypto/ee327174-46a8-4392-a3a5-8fdf76b3c984n%40mozilla.org?utm_medium=email&utm_source=footer>.


-- 
You received this message because you are subscribed to the Google Groups "[email protected]" group.
To unsubscribe from this group and stop receiving emails from it, send an email to [email protected].
To view this discussion on the web visit https://groups.google.com/a/mozilla.org/d/msgid/dev-tech-crypto/93ad096f-c3bd-fcbe-60aa-c0cd31582328%40redhat.com.