Should X509 certificate have nonRepudiation bit set to check PKCS7 signature? - certificate

X509 certificate has set of keyUsage bits. Two of them are
digitalSignature
nonRepudiation (recent editions of X.509 have renamed this bit to contentCommitment).
I read X509 RFC (https://www.rfc-editor.org/rfc/rfc5280) and it talks about general usage of these bit.
And I read PKCS7 RFC (https://www.rfc-editor.org/rfc/rfc2315) and it talks about PKCS7 structure and so on and doesn't specify which bits needs to be set.
Is there any RFC or other specification which identifies whether one or both of them should be set?
Regards,
Victor

A PKCS#7 file generally contains a chain of certificates. That is, a Root CA certificate, any intermediate CA certificates that apply, and then the endpoint certificate (SSL, e-mail, etc.) A PKCS#7 is typically used to bundle these up into a single file. It's useful, in that you can import the entire chain at once into a keystore or other relying application.
As to the key usage bits, those are set depending on the needs and purpose of a particular certificate. For example, a Root CA certificate would typically have both digital signature and non-repudiation set. For an SSL certificate, you may find key encipherment and digital signature. There's really no correlation between key usage and PKCS#7 files, unless you're talking about the CA certificates contained in the PKCS#7 file.

BTW, this bit violates the separation of concerns in its design. Non-repudiation is a legal issues negotiated on the business level. Using the bit at the certificate/signing level is irrelevant. See e.g. http://www-personal.umich.edu/~lsiden/tutorials/signed-applet/ShockingTruth.html

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.

Is there a standard on how to sign primitive types?

I am designing a protocol to exchange IOUs (digital promissory notes).
These should be digitally signed, but the signature should be independent from the data representation (whether its XML, JSON, binary, little or big endian numbers).
Is there any standard on how to sign a list of strings and primitive types (like integers, floating points, booleans)?
There isn't one standard encoding, but you can specify canonical forms for particular encodings.
For json you could specify that there is no whitespace outside strings and that keys should be sorted in a particular way.
For ASN.1 there is DER encoding, which is the canonical form of BER.
There is Cryptographic Message Syntax (CMS), but I don't know much about it.
The better question is what is the best format for verifying digitally signed Data primitives.
The answer is xml formatted and signed according to the XAdES standard. XAdES is harmonized with the related standards and many implementations participate in interoperability tests hosted by etsi.
Unless it is easy to verify a digitally signed format, the signature has limited value.
You can sign any bit stream and store/maintain the signature as a detached signature. But then you and the relying parties (the recipients) need to deal with two files. One for the data and one for the signature.
The advantage of xml with XAdES is that the format enables the signed xml file to include the digital signature.
You can create an equivalent of XAdES for another data format such as json. But a new format has limited use unless it becomes popular and standardized. XAdES has already accomplished this, so it is the way to go.
Added
Re: comment--
I want to provide non-repudiation. I understand that I have to save the information I signed. But I was hoping that I don't have to save it as XML but could rather save all values included in the signature in a database (less verbosely) and uniquely reconstruct the signed string from them before verifying.
Technically, you can do that. You'll need to watch out for spacing issues within the xml. But practically, not a good idea. Why:
Proving non-repudiation requires that you meet the applicable burden of proof that the alleged signer really did sign the data.
You may be trying to convince the original signer of this, an expert third party (an auditor) or non-experts (lawyers and juries). You want to make it easy and simple to convince these people. Schemes such as "re-creating" the signed file are not simple to understand compared with "here is the original signed file. Its signature verifies and it was signed with the digital certificate belonging to Susan Signer."
To keep it simple, I'd suggest signing an XAdES XML file. Then extract the data from the file and use it in your dbms. Hang on to the original signed file in your dbms or elsewhere. In case of a dispute, produce the original file and show that it verifies. A second part of the audit would be to show that your dbms has the same data values as the signed XML.
The programming and storage costs of hanging on to the original, signed, xml file are de minimis, when compared with your goal of proving non-repudiation of the data.
By the way, how is the signer's certificate managed? If it is anything less than a QSCD (Qualified Signature Creation Device), such as storing the cert in the file system, then you have another problem: no way to conclusively prove that the certificate wasn't used by an imposter. Use a secure system for signing such as CoSign (my company) or an equivalent system.

FairPlayKeyData apple activation

has anybody seen something like that?
-----BEGIN CONTAINER-----
AAEAAbhNth6wR78Jv94ci38B8XFG0Q1xdb2+JXji2RATYKGibZb41Syi1j/gB7oH
62qFCGdG2cFPm8Kj5eDDb6lpqW3WKmTPhMZE2aa/GCClgOPNu/Qqfb2vqWAwvgHy
.........
3jGzdXy6d4h7yfhycVcM2OtoE0eM701TpxWSPyjPawe6VKndfNN8C881iwiABFfN
qCtsUB+OxDDeJndc3VVxMEEPC2JujTbElPi/ekt1Xr2gHYLa
-----END CONTAINER-----
what does this container means? how it is generated?
iTunes send to apple FairPlayCertChain certificate and FairPlaySignature, apple responds with FairPlayKeyData and other info...
An introduction to Fairplay DRM can be found on page 2 of
http://teal.gmu.edu/courses/ECE646/project/reports_2007/AD-1.pdf
More about White-Box DES (what's behind the DRM) and one implementation of generating such containers:
https://crypto.stanford.edu/DRM2002/whitebox.pdf
Abstract of the second PDF:
For applications such as digital rights management (drm) solutions employing cryptographic implementations in software, white-box cryptography (or more formally: a cryptographic implementation designed to withstand the white-box attack context) is more appropriate
than traditional
black-box
cryptography. In the white-box context, the
attacker has total visibility into software implementation and execution,
and our objective is to prevent the extraction of secret keys from the
program. We present methods to make key extraction difficult in the
white-box context, with focus on symmetric block ciphers implemented
by substitution boxes and linear transformations. A
des
implementation
(useful also for triple-
des
) is presented as a concrete example.
If such information is not what you're looking for, please be more thorough in your question.

PKCS11 Import Encrypted PKCS1 RSA Private Key

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

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.