The application is quite simple.
It accepts a PKCS8 EC private key (DER format), X.509 certificate and file
to sign as params.
It proceeds to then extract the private/public keys.
Create a signer for SHA384/ECDSA.
Then proceed to sign/verify the file.
This all works when using RSA's "JsafeJCE" as the CryptoProvider for the EC
algorithms.
But when I switch to Mozilla JSS/NSS/NSPR "Mozilla-JSS" for the
CryptoProvider, I encounter issues.
I'm using the following versions for my current testing:
JSS 4.3.1
NSS 3.12.6 with nspr 4.8.4
I've rebuilt from source with the following extra build flags set:
NSS_ENABLE_ECC=1
NSS_ECC_MORE_THAN_SUITE_B=1
Until I rebuilt with these ECC flags, the JCASigTest was failing the EC
tests.
But now those tests all work fine including this one which is what I need to
do:
sigTest("SHA-384/EC", keyPair);
This test creates it's own keyPair so the private key is already stored when
signing occurs.
Due to this, retrieval of the PrivateKey works just fine.
But my test fails when JSS requests NSS to generate the PrivateKey.
Here is my test (prior to this, I have initialized CryptoManager, set thread
token, logged into token, etc)
private PrivateKey getECPrivateKey(final byte[] privateKeyBytes)
{
PrivateKey privateKey = null;
try
{
final PKCS8EncodedKeySpec privKeySpec =
new PKCS8EncodedKeySpec(privateKeyBytes);
final KeyFactory factory =
KeyFactory.getInstance("EC", "Mozilla-JSS");
privateKey =
(org.mozilla.jss.crypto.PrivateKey)factory.generatePrivate(privKeySpec);
}
catch (.....)
return privateKey;
}
This exception is thrown:
java.security.spec.InvalidKeySpecException: TokenException:
org.mozilla.jss.crypto.TokenException: Failed to import private key info:
(0) Unknown error
at org.mozilla.jss.pkcs11.PK11PrivKey.fromPrivateKeyInfo(Native Method)
at
org.mozilla.jss.pkcs11.PK11PrivKey.fromPrivateKeyInfo(PK11PrivKey.java:122)
at
org.mozilla.jss.pkcs11.PK11PrivKey.fromPrivateKeyInfo(PK11PrivKey.java:110)
at
org.mozilla.jss.provider.java.security.KeyFactorySpi1_2.engineGeneratePrivate
(KeyFactorySpi1_2.java:212)
at java.security.KeyFactory.generatePrivate(Unknown Source)
at CryptographicInterface.getECPrivateKey(CryptographicInterface.java:608)
Tracing this down to the NSS Native routine fromPrivateKeyInfo, I find the
issue here:
File:
nss-3.12.6-with-nspr-4.8.4\mozilla\security\nss\lib\pk11wrap\pk11pk12.c
Routine: PK11_ImportPrivateKeyInfoAndReturnKey()
The switch statement handles only 3 Private key SEC OID's as follows:
SEC_OID_PKCS1_RSA_ENCRYPTION = 16
SEC_OID_ANSIX9_DSA_SIGNATURE = 124
SEC_OID_X942_DIFFIE_HELMAN_KEY = 174
Unfortunately, our SEC OID is this:
SEC_OID_ANSIX962_EC_PUBLIC_KEY = 200
So the switch handles this as the default case and passes back NULL.
Is it possible to add NSS support for decoding this type of Private Key?
Or is there another means I can use to gain access to the Private Key I can
use for signing?
I also chased down the PKCS12 path.
I converted my key to PKCS12, then attempted to use it to gain access to the
Private Key.
It eventually fails in the same manner when I attempt to read the key from
the KeyStore like this:
Key key = ks.getKey(alias, pw);
It seems this thread was applicable to my issue:
http://old.nabble.com/How-to-export-private-key-using-pk12util-td23203644.html
But this thread speaks of avoiding a security trap when exporting private
keys in PKCS#8 format.
So I guess this isn't supported on purpose?
Peder Nielsen
--
View this message in context: http://old.nabble.com/Extracting-PrivateKey-from-PKCS8EncodedKeySpec-with-EC-tp31354778p31354778.html
Sent from the Mozilla - Cryptography mailing list archive at Nabble.com.
As I had stated below, NSS disallows DER decoding of the EC Private key.
I found the supported way to do this is to package the key/cert into a
PKCS12 file.
Then import this into the key/cert databases supported by NSS.
Once this is done, NSS will read in the databases and store on an internal
PKCS11 crypto token.
The private/public keys may then be retrieved from the token and used for
file signing.
Here is what I had to do with my PKCS8 DER encoded EC key and X509 DER
certificate.
Convert X.509 certificate from DER to PEM
> openssl x509 -in ./cert.der -inform DER -out ./cert.pem -outform PEM
Convert PKCS8 DER encoded Private key to PEM
> openssl pkcs8 -in key.p8 -out key.pem -outform PEM -inform DER
-nocrypt
Cat together into 1 file
> cat cert.pem > pks12.pem
> cat key.pem >> pks12.pem
Now package into a PKCS12 with alias and password of choice
> openssl pkcs12 -export -in pks12.pem -out test1.p12 -name "alias"
-passout "pass:password"
PKCS12 file must now be imported into database supported by JSS/NSS
Use cmd utility supplied by NSS named pk12util
> pks12util -i test1.p12 -d <dbdir>
Prompts appear for the following:
> Enter Password or Pin for "NSS Certificate DB":
> Enter password for PKCS12 file:
Enter appropriate passwords for both NSS database files and PKCS12 file
being imported
Execute program using this specific NSS database to access PKS12 package
Appropriate passwords and alias are required to sign a file with a
specific key
I hope this helps others struggling with such an issue.
One would think NSS would support a method given user supplied key and
certificate.
But in the interest of security, the supported method is definitely more
secure.
The private key is never in the clear, it is protected at all times.
I used JSS for my application as it is Java based.
Same would hold true for C based applications which use the NSS/NSPR libs.
Peder Nielsen
--
View this message in context: http://old.nabble.com/Extracting-PrivateKey-from-PKCS8EncodedKeySpec-with-EC-tp31354778p31380949.html
NSS pk11wrap layer has two functions to create private keys in a token: PK11_ImportEncryptedPrivateKeyInfo and PK11_ImportAndReturnPrivateKey.
But only 1st of them supports EC keys. You may try resurrect the bug activity.
Regards,
Konstantin
On 12.04.11 20:52, Peder Nielsen @ GecoInc wrote:
>
> Nobody replied to this post but I did find a solution.
> <...>
>
> Peder Nielsen @ GecoInc wrote:
>>
>> I am attempting to port a Java based FileSigner application from RSA BSAFE Crypto-J 4.0 to Mozilla JSS.
>> <...>
>>
>> Tracing this down to the NSS Native routine fromPrivateKeyInfo, I find the issue here:
>> File: mozilla\security\nss\lib\pk11wrap\pk11pk12.c
>> Routine: PK11_ImportPrivateKeyInfoAndReturnKey()
>>
>> The switch statement handles only 3 Private key SEC OID's as follows:
>> SEC_OID_PKCS1_RSA_ENCRYPTION = 16
>> SEC_OID_ANSIX9_DSA_SIGNATURE = 124
>> SEC_OID_X942_DIFFIE_HELMAN_KEY = 174
>> Unfortunately, our SEC OID is this:
>> SEC_OID_ANSIX962_EC_PUBLIC_KEY = 200
>>
>> So the switch handles this as the default case and passes back NULL.
>>
>> Is it possible to add NSS support for decoding this type of Private Key? Or is there another means I can use to gain access to the Private Key I can use for signing?
>> <...>
>> Peder Nielsen