Task #3048
closedCreate ndn-tlv based private key wrapper
100%
Description
Tpm provide private key import and export functionalities. When exporting a private key, we need to encrypt the private key and store it in a container. In our earlier implementation, we follow the PKCS #5 and #8, and encode information in DER format. As a part of certificate refactoring (basically getting rid of the dependency on DER encoding), we also want to encode private key wrapper in ndn-tlv. The new encoding would be (Note that the high level abstraction stays same with PKCS #5 and #8, just use different encoding):
PrivateKeyWrapper ::= PRIVATE-KEY-WRAPPER-TYPE TLV-LENGTH
EncryptSalt
EncryptIteration
EncryptParams
EncryptedKey
EncryptSalt ::= ENCRYPT-SALT-TYPE TLV-LENGTH
BYTE+
EncryptIteration ::= ENCRYPT-ITERATION-TYPE TLV-LENGTH
NonNegativeInteger
EncryptedKey ::= ENCRYPTED-KEY-TYPE TLV-LENGTH
BYTE+
EncryptParams ::= ENCRYPT-PARAMS-TYPE TLV-LENGTH
EncryptAlgorithm
EncryptInitialVector?
EncryptAlgorithm ::= ENCRYPT-ALGORITHM-TYPE TLV-LENGTH
NonNegativeInteger
EncryptInitialVector ::= ENCRYPT-INITIAL-VECTOR-TYPE TLV-LENGTH
BYTE+
This involves implementation of two classes: PrivateKeyWrapper
and EncryptParams
.
The reason for this separation is that EncryptParams may be used for other encryption cases.
All tlv types are application specific:
enum {
// Encryption parameters
Params = 128,
Algorithm = 129,
InitialVector = 130,
// Password wrapper
Salt = 131,
Iteration = 132,
// Payload
PayLoad = 133,
// Private key wrapper
PrivateKeyWrapper = 134,
EncryptedKey = 135
};
Some values are defined as:
enum AlgorithmValue {
// Block cipher
BlockCipherAesCbc = 0,
BlockCipherDesEde3Cbc = 1,
};
Updated by Yingdi Yu over 9 years ago
- Assignee set to Zhiyi Zhang
- Target version set to v0.4
Updated by Yingdi Yu over 9 years ago
- Blocks Task #2926: Refactor KeyChain added
Updated by Junxiao Shi over 9 years ago
What's the rationale of eliminating DER encoding?
Updated by Yingdi Yu over 9 years ago
Junxiao Shi wrote:
What's the rationale of eliminating DER encoding?
OpenSSL does not provide DER encoding API (it has internal implementation), CryptoPP exposes part of DER API. As a result, we either implement our own DER endec or use TLV instead. DER is just another type of Type-Length-Value encoding scheme, so we do not really need DER if we have TLV.
Updated by Junxiao Shi over 9 years ago
The spec should be placed into docs/
, and the rationale needs to be explained in ndn-cxx Application Developer Guide. Both can be done either in this issue or in other issues, but the spec commit needs to come before the implementation.
Updated by Yingdi Yu over 9 years ago
- Status changed from New to Code review
- % Done changed from 0 to 70
Updated by Yingdi Yu over 9 years ago
Junxiao Shi wrote:
ndn-cxx Application Developer Guide
where is this?
Updated by Junxiao Shi over 9 years ago
Reply to note-7:
I answered this before.
http://www.lists.cs.ucla.edu/pipermail/nfd-dev/2014-December/000673.html
Updated by Alex Afanasyev over 9 years ago
May be a stupid question, but can we instead of this define a common encryption procedure and just use it for encrypting private keys when exporting is needed? Is there anything special we are doing specifically with private keys?
Updated by Junxiao Shi over 9 years ago
The spec in commit:e9266e34a034f4ac229220002c8c87268c1ff8fc defines private key wrapper, which contains an NDN private key encrypted by a symmetric encryption algorithm, and also the parameters of the symmetric encryption algorithm; the symmetric key is derived from a password.
There are two categories of symmetric encryption algorithms: block cipher and stream cipher.
A typical block cipher takes as input:
- a key of certain length (length is determined by the cipher)
- an initialization vector (length is determined by the cipher)
- the mode of operation
- a padding algorithm (to pad the plaintext to be a multiple of the cipher's block size)
- the plaintext
It's unclear from the spec:
- How the key is derived from a password?
- Which padding algorithm is used?
- How the
Salt
andIteration
fields in the private key wrapper is used?
Technically private key wrapper does not depend on the key-derivation algorithm, but then all mentions of "password" should be replaced with "key", and key-derivation algorithm can be defined in another document.
I'm unfamiliar with stream ciphers so I don't know whether there's enough fields for those.
If the design is intended for block ciphers only, say that.
Updated by Yingdi Yu over 9 years ago
Alex Afanasyev wrote:
May be a stupid question, but can we instead of this define a common encryption procedure and just use it for encrypting private keys when exporting is needed? Is there anything special we are doing specifically with private keys?
I think it is pre-mature to define a common encryption procedure for now, we haven't accumulate enough experience...
Updated by Yingdi Yu over 9 years ago
Junxiao Shi wrote:
There are two categories of symmetric encryption algorithms: block cipher and stream cipher.
We did not invent the idea of using block cipher. PKCS standard only adopts block ciphers for key encryption.
I think the reason of using block cipher is pretty obvious. The private key is not a stream...
It's unclear from the spec:
- How the key is derived from a password?
- Which padding algorithm is used?
- How the
Salt
andIteration
fields in the private key wrapper is used?
previously, I was thinking about TLV format only. I will add details into the spec.
Technically private key wrapper does not depend on the key-derivation algorithm, but then all mentions of "password" should be replaced with "key", and key-derivation algorithm can be defined in another document.
No, we should keep password, the reason is that password is used to derive the symmetric key for private key encryption. Using password can explicitly distinguish itself from symmetric key and private key.
I'm unfamiliar with stream ciphers so I don't know whether there's enough fields for those.
If the design is intended for block ciphers only, say that.
Why? stream cipher is not supposed to use here. I don't understand why you want to make it complicated.
Updated by Yingdi Yu over 9 years ago
I just dig out that Mac OS X KeyChain can provide wrapped PKCS8 private key, this wavies the need of encrypted private key. I will do some tests to see the inter-operability.
Updated by Yingdi Yu over 9 years ago
It turns out that Mac OS X KeyChain can create ShroudedPrivateKey (i.e., WrappedPkcs8), the only problem is that it requires GUI to acquire user's permission, so that it won't work with pure terminal mode (but openssl is not subject to the GUI).
So there are three solutions:
We use Mac OS X KeyChain service to prepare wrapped private key, and do not suggest people to use OS X keychain based tpm in terminal only environment.
We export raw private key bits from Mac OS X KeyChain, and use OpenSSL to prepare the wrapped private key.
I prefer the second approach. But in any of the two cases, we do not need to define our own EncryptedPrivateKey wrapper, we only need SafeBag, which contains WrappedPkcs8Format private key and certificate.
Updated by Alex Afanasyev over 9 years ago
Touching anything in OSX KeyChain requires GUI and user involvement, so I don't see a big difference between two cases. For non-terminal uses, OSX keychain/tpm cannot be really used...
Updated by Yingdi Yu over 9 years ago
Alex Afanasyev wrote:
For non-terminal uses, OSX keychain/tpm cannot be really used...
You mean "for TERMINAL uses, OSX keychain/tpm cannot be really used" right?
Updated by Alex Afanasyev over 9 years ago
Yes, I mistyped. I meant to say non-GUI uses.
Updated by Junxiao Shi over 9 years ago
Reply to note-13:
I agree with not allowing stream ciphers, but this design limitation should be stated: after "the private key is encrypted using a symmetric key", append "with a block cipher".
Reply to note-15:
What's the solution for linux?
Updated by Junxiao Shi over 9 years ago
- Status changed from Code review to Closed
- % Done changed from 70 to 100