PKCS11 Import Encrypted PKCS1 RSA Private Key - pkcs#11

I have a simple straight question: Can an encrypted PKCS1 RSAPrivateKey be imported into a PKCS11 compatible security module without exposing the private key in the client's memory?
I know that PKCS11 explicitly mentions PKCS8's PrivateKeyInfo as the required private key format in order to import it in through the C_UnwrapKey function.
Any help please!

Whether private key is exposed in the host memory during the unwrapping fully depends on the implementation of your PKCS#11 module.
RSA keys are usually wrapped with symmetric keys (i.e. AES) and sadly many PKCS#11 modules shipped with common smartcards implement symmetric encryption algorithms in software. Unwrapping in such cases consists of two steps:
software based decryption of key material which is stored in the host memory
import of decrypted key material into the device
However there are also PKCS#11 implementations (and devices) that implement symmetric encryption algorithms in hardware and these are capable of performing unwrapping of RSA keys without exposing private key into the host memory.
You can use C_GetMechanismInfo() function to find out whether your PKCS#11 module performs specific algorithm in hardware or not. Just examine the "flags" member of returned CK_MECHANISM_INFO structure for the presence of CKF_HW flag.
Edit: PKCS#1 to PKCS#8 conversion
As far as I know PKCS#11 does not specify any standard method for PKCS#1 key unwrapping or conversion. Also the last time I have worked with Luna SA HSM there was a statement in the documentation that it expects imported key material to be in PKCS#8 format.
You can try to convert PKCS#1 key to PKCS#8 in software, but I am afraid it won't be possible without decryption of private key into the host memory. It is rather easy to convert unencrypted PKCS#1 key to the PKCS#8 one - you just insert PKCS#1 RSAPrivateKey sequence into the PKCS#8 PrivateKeyInfo sequence, specify version, privateKeyAlgorithm and you are done. But to convert encrypted PKCS#1 key (whole RSAPrivateKey sequence is encrypted) you first need to decrypt it, convert it to PKCS#8 PrivateKeyInfo sequence, then encrypt PKCS#8 PrivateKeyInfo sequence, insert encrypted PrivateKeyInfo into EncryptedPrivateKeyInfo sequence and specify encryptionAlgorithm.

Yes, you can! Use the pkcs11-tools --keypairgen option to do so.
e.g.
pkcs11-tool --module /usr/local/lib/opensc-pkcs11.so -l --pin 648219 --keypairgen --key-type rsa:1024 --id 10
See
http://linux.die.net/man/1/pkcs11-tool
https://github.com/OpenSC/OpenSC/wiki/SmartCardHSM
for more details

Related

How to use SHA512 hashing algorithm with elliptic curve to sign, in PKCS11Interop?

In am using PKCS11Interop in C#, i got CKR_MECHANISM_INVALID error while trying to use method Sign. The key object i am using is of mechanism type CKM_EC_KEY_PAIR_GEN . but at signing time, i use mechanism CKM_ECDSA_SHA512 .
I tried to define key mechanism as CKM_ECDSA_SHA512 at key-pair generation time, but it seems that this key type needs some attributes that i don't know. The attributes i am using is similar to the correct version of this question, but it seems using hash algorithms need some thing more.
Please guide me how should i use SHA512 hash algorithm with ECDSA elliptic key.
Your unmanaged PKCS#11 library most likely does not support CKM_ECDSA_SHA512.
By returning CKR_MECHANISM_INVALID error your unmanaged PKCS#11 library is telling you that "An invalid mechanism was specified to the cryptographic operation". You can use GetMechanismInfo() method to check whether the mechanism is supported:
if (!slot.GetMechanismList().Contains(CKM.CKM_ECDSA_SHA512))
throw new Exception("Unmanaged PKCS#11 library does not support CKM_ECDSA_SHA512 mechanism");
However CKM_ECDSA_SHA512 (hashing and signing) mechanism is used rather rarely. It's much more common and efficient to compute SHA512 hash in your application and then sign it with CKM_ECDSA (just signing) mechanism.

Same ciphertext for same text

Is it possible to set up AWS KMS in a way so that it would generate same ciphertext for the same text (e.g. alpha) each time?
And if not, what others cryptographic methods should I use? (it would be great if they have libs for node.js as well)

How to Fingerprint a JWK?

Is there a standard, canonical method for creating a fingerprint (aka thumbprint) for a JWK?
From what I was reading it seems that the standard doesn't define how a kid should be specified, which I find odd. To me it makes the most since to have it be a deterministic value rather than one that requires a lookup table such that others could easily recreate the key id in by virtue of possessing the public key.
I am aware that SSH fingerprints and X.509 thumbprints are standardized, but those don't seem like a suitable solution for all environments where JWKs are used (especially browsers) because they are too complex for naive implementations and including the libraries capable of manipulating such (i.e. forge) would waste a lot of memory, bandwidth, and vm compile time.
Update
Officially it's called a "thumbprint" not a "fingerprint".
I think the RFC7638 will answer your question.
This RFC describes a way to compute a hash value over a JWK.
It is really easy to implement:
Keep the required parameters only. For a RSA key: kty, n and e and for an EC key: crv, kty, x and y.
Sort those parameters in lexicographic order: e,kty and n
Compute the parameters and values into Json: {"e":"AQAB","kty":"RSA","n":"0vx7agoebGcQSuuPiLJXZptN9nndrQmbXEps2 aiAFbWhM78LhWx4cbbfAAtVT86zwu1RK7aPFFxuhDR1L6tSoc_BJECPebWKRXjBZCi FV4n3oknjhMstn64tZ_2W-5JsGY4Hc5n9yBXArwl93lqt7_RN5w6Cf0h4QyQ5v-65Y GjQR0_FDW2QvzqY368QQMicAtaSqzs8KJZgnYb9c7d0zgdAZHzu6qMQvRL5hajrn1n 91CbOpbISD08qNLyrdkt-bFTWhAI4vMQFh6WeZu0fM4lFd2NcRwr3XPksINHaQ-G_x BniIqbw0Ls1jF44-csFCur-kEgU8awapJzKnqDKgw"}
Hash it using SHA-256 and encode it into Base64 Url Safe: NzbLsXh8uDCcd-6MNwXF4W_7noWXFZAfHkxZsRGC9Xs
I don't believe there is a true standard, but this topic has been discussed in the IETF mailing archives. While the conversation seemed to get a little side-tracked by whether or not canonical JSON was a good idea in general, there was one method that seems reasonable as a standard fingerprinting method.
Remove all "metadata" fields from the JWK (where in this case "metadata" is defined as any non-required key, ie anything but "kty" and the parameters for the encryption algorithm defined by the JWA RFC-7518).
Convert stripped JWK into "canonical" JSON (sort keys lexicographically, no leading or trailing whitespace, and no whitespace between tokens).
Compute digest over created JSON string.
There is also no true standard that I am aware of for canonical JSON, but all the sources I've seen agree on at least the rules listed above (which are the only rules that should be relevant for the types of objects used for JWK's).

Encrypt NSString with RSA Algorithm with known modulus and exponent keys in iOS

In iOS app, I need to encrypt NSString with RSA Algorithm, I have known public modulus and exponent key.On Android side they have used bouncy castle ApI for RSA Encryption.Can some one help me how to encrypt how can I encrypt NSString with these Public Modulus and Exponent key as could generate similar encryption as in Android.I have looked on many source code available but could not generate the correct encryption.Any help would be highly appreciated.
Modulus key That I have is "117130940722358865944076735715016871148960803304334901248996815419815052552875336322790410991392433604701394608500231884113911915168625416296669114728862690539451024021812353340986348428958506523689933432584403548435474622224828221548841371083486321081622447517054022904372023020885356296462823306439795173749"
Exponent is "65537"
Please help me to encrypt NSString with RSA Encryption.
Being in iOS, you probably need to work without extra libs like OpenSSL. But to do so, you must have some kind of "big numbers" library. I am not using iOS, but a search gives this mention of "huge numbers" library, discussed here: Store and perform operations with huge numbers in iOS
With this library, you need only RSA formulas. Fast search gives this article http://www.linuxjournal.com/article/6695, you don't need to all of it, just scroll down to mention of ModExp - this is an operation you need to encrypt a message when you have key and modulus available.
You can use openSSL for this
https://www.openssl.org/docs/man1.1.0/crypto/RSA_public_encrypt.html
#include <openssl/rsa.h>
int RSA_public_encrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
int RSA_private_decrypt(int flen, unsigned char *from,
unsigned char *to, RSA *rsa, int padding);
Be aware of export compliance though
Using SSL in an iPhone App - Export Compliance
You may be better trying to get the Common Crypto equivalent to work

Safe to store AES cipher parameters (blocksize/blockmode/keysize etc) in file header?

Is it 'safe' to store cipher parameters in the (unencrypted) header of an encrypted file? Is there anything (other than the key of course!) that shouldn't be stored/transmitted in the clear?
You are using a symmetric encryption, where storing the blocksize, blockmode and keysize would be safe, since you don't (mustn't) make keys available as you stated.
But all such params are in general useful to attackers. If the file cannot easily be associated with a cipher and used params (or the software respectively), an attacker would have considerably more work to do and that's what encryption basically is for. A cipher is secure, while (and because) everyone can see how it works. Additionally trying to hide some information can also add some security.
AES has a fixed block size of 128bits, which itself is not a critical information, knowing of AES itself already. So this one is not needed inside the file header.
The keysize is given by the key itself, so it can be left out too.
The blockmode is the remaining parameter. Just never use ECB. Permanently use a single blockmode like OCB and you don't need to store it in the file aswell.
Predefining all params at both sides is a solution, if you don't intend to change them per file.
Error checking can be done using checksums, which are also critical information, so you may encrypt them together with the data or provide them together with the key.
Perhaps, following approaches can help if you have to transmit the params anyway:
Transmit params in the key file, if you're up to define the format yourself and the keys were distributed on a per file basis.
You could also define different settings by mapping them to some randomly defined enumerators, which don't provide valuable information without knowing the software.