Primary Key for X509 Certificate KVStore - x509certificate

I'm going to store root and intermediate certificates (from different CA) into some KVStore.
The problem: I have a leaf certificate (only) that I want to validate based on certificates from my store. The leaf certificate has Authority Key Identifier == Subject Key Identifier of a parent that already must be present in the KVStore.
Question: What should I use as a Key in KVStore?
1.Subject Key Identifier:certificate or it can be the same within single CA or different CAs. what about renewal or keys rotation?
2.Subject Key Identifier + Subject DN: certificate - not sure that there is a difference with first.
3.Subject Key Identifier: list[certificate]
4.Serial Number + Issuer is unique but leaf certificate doesn't contain this date about parent.

The Subject Key Identifier is a hash value over the certified public key. Thus, depending on the CA's key rotation policy this may or may not change during certificate renewal. It is therefore not guaranteed that the mapping SKI:certificate is unique.
A combined index as in option 2 does not change that.
Option 4 should be ruled out since the child certificate does not know the issuer and serial number of its parent.
Option 3 may be a valid solution in most cases, however, the Authority Key Identifier extension is not mandatory for X.509 certificates. So you may have to deal with leaf certificates without the AKI extension.
This typically leads to option 5: Subject DN: list[certificate]. Preferably with a sorted list that has the most likely CA certificate on top.
However, if your application only deals with leaf certificates with an AKI extension and all CA certificates require a key rotation during renewal option 1 may be a tick more performant. In that case I'd also keep an entry Subject DN: list[Subject Key Identifier].

Related

Confused about participants/signers when using Accounts library with Tokens SDK

I just started reading/experimenting with the Accounts library yesterday and trying to wrap my head around the participants/signers part in my states.
Let's say I have the following:
1. Mint: A node that issues tokens.
2. Registry: A node that hosts accounts and generates key pairs for them when requested.
3. Wallet: A node that holds tokens on behalf of accounts.
4. I created my own fungible token which basically has an extra field: PublicKey owningAccount
The process:
1. The Registry creates a new account (let's call it Account001), so the Registry is the host of that account.
2. The Mint requests a new key pair for Account001 from Registry
3. The Mint issues a new token to Wallet and sets owningAccount to the key they got for Account001 from Registry, so now Wallet is the holder of the token
So now we have:
1. Registry is the host of Account001
2. Wallet is the holder of the token (on behalf of Account001)
Questions:
1. Is my approach of having those 3 nodes correct? One node controls the supply of tokens, another the users, and last one tracks the "balances" of tokens per user.
2. I want to keep this separation of nodes (assuming it's conceptually correct); and for that reason I don't want to include the owningAccount as part of the participants for the token, so the token will only persist in the vault of Wallet, BUT I will require owningAccount as a signer for various commands (e.g. when moving the token to a new owningAccount; both the holder (i.e. Wallet) and the owner (i.e. Registry on behalf of owningAccount) must sign).
3. In general (let's forget about tokens), if I have a node that manages users and another that manages the state that has owningAccount field, in that state do I need to have owningAccount as a participant? Like I mentioned I'm still trying to figure out the "right" approach (usually things become more clear as I program more), but I would imagine that there should be some decoupling where the owningAccount is just required as a signer for commands related to states that are tied to it, and the participant is mostly just the node to whom that state was issued to.
Roger Willis explained to me on Slack how FungibleToken allows assigning the token to a certain owner (i.e. public key) as opposed to a Party by using the Holder attribute; the process is as follows:
1. The Mint node starts the issue token flow which takes as inputs amount and AccountInfo ref
2. It requests a new public key for the referenced AccountInfo from the Accounts Registry node
3. The received public key is used to get the respective party (i.e. identityService.partyFromKey(receivedPublicKey))
4. The resulting party is assigned as the Holder of the token
5. Remember that a Party is the CordaX500Name (Accounts Registry in our case) and a public key that identifies this entity (in our case it's the public key that mapps to an AccountInfo state (i.e. to a certain user)).
6. So whenever we issue a new token, the holder will always be Accounts Registry party but the same party will have different public keys for different owners/users.
7. With all that being said we no longer need 2 nodes Accounts Registry and Wallets, we will have one node Wallets which holds our AccountInfo states and our tokens where the holder of the tokens is Wallets party but the public key in that party will vary and map to different AccountInfo states depending on who's the owner/user.

What's the relashionship between the network-root-truststore and nodekeystore?

Why does the Node need the network-root-truststore.jks file at initial registration? What's the relashionship between this file and the nodekeystore.jks?
EDIT: Actually, I was meant that I didn't see the relashionship between the CSR and the network-root-truststore.jks file. Is it not possible to generate the Certificate Signing Request without this file?
network-root-truststore.jks-> This is the network operator's root CA.
nodekeystore.jks -> This contains nodes identity key pairs and certificates.
As you can see in the diagram. The Root CA for Doorman and Network Map are same. The node assumes 3 level hierarchy as you can see in the picture above. ( This got fixed in version 3.3 so you can have a n-level certificate hierarchy)
For initial registration with the doorman, you'd need to create a CSR request and send it to the doorman, the doorman will then return you the requestId, Using the provided requestId you'll ask the doorman if the CSR has been signed by him or not once done, Doorman will hand you over the node certificate like below
Once you've the node certificate signed by the doorman, you want to validate it (for this you'd need the RootCA Certificate which is inside the network-root-truststore.jks now you don't need it to create the CSR, but the certificate received must be validated, as result, you need this. Also, this prevents man in the middle attack.)and generate the TLS key pair and certificates.
The above process is automatically done by the corda node for you at the time of initial registration when you start the node using this command -> java -jar corda.jar --initial-registration --network-root-truststore-password <trust store password>
One Important thing is you should remove or delete the network-root-truststore.jks file once you are done with the registration.

When can CertGetCertificateChain return multiple simple certificate chains?

Why does CertGetCertificateChain have a facility to return more than one"simple chain"? What are simple chains and what other type of chains should I expect?
On a test run passing a certificate such as the following...
root
|- parent
|- my certificate
...the result was one simple chain:
0. my certificate
1. parent
2. root
In what case will we see more than one simple chain returned?
Multiple chains may appear whan there are multiple paths from single leaf certificate through multiple CA certificates.
This occurs in two (major) cases:
two or more CA certificates share the same Subject and public key. This happens when CA certificate is renewed with the same key pair. This will result in two very similar certificates which can be used as a node in the certification path building. They are different, but they both (since Subject and public key are shared) can be used to validate the signature of the issued certificate.
when cross-certification is used to provide additional paths to (possibly) a different root certificate. Litreally the same as above, with the exception that this option is used to provide routes to different CA roots.
Single certificate chain is just single path from a collection of all possible paths.

SID in Active Directory

I am working with a Windows Active directory environment. The SID is the combination of Domain ID and RID.
I found that there can be a maximum of 2^32 RID for a domain. However, the Domain ID can be even more than 32 bits. Also it seems that domain ID is unique only within the forest. I wonder why Microsoft allotted so many bits for Domain ID. Is there any other significance for the Domain Identifier part?
To be precise I have only 3 domain in my forest. Why does server the following ID for the user object?
objectSid: S-1-5-21-2999047449-515994586-265227950-1125
In case this ID is Universally Unique then who assigns this Domain ID?
A SID is not a GUID, it is not intended to be huge unique identifier with trillions of unique values, it is an arbitrary length STRING containing various information which includes the domain ID and the relative ID.
For example, S-1-5-7 is the SID for Anonymous users, S-1-5-32-545 is the SID for the local Users group and S-1-5-32-544 is the SID for the local Administrators group. These SIDs are common to all installations and therefore known as well-known SIDs. See: http://support.microsoft.com/kb/243330
As for who assigned your domain ID, it is randomly generated when the domain is created. It is only unique so far as a new domain will not use an ID already in use within the Forest, but there could be hundreds of domains out there with the same ID.
SID (Security Identifier) :- SID is the primary key for any object in an active directory. SID are unique to a domain.
In active directory users refer to accounts by using the account name , but the operating system internally refers to account by their security identifier (SIDs).

Security review of an authenticated Diffie Hellman variant

EDIT
I'm still hoping for some advice on this, i tried to clarify my intentions...
When i came upon device pairing in my mobile communication framework i studied a lot of papers on this topic and and also got some input from previous questions here. But, i didn't find a ready to implement protocol solution - so i invented a derivate and as i'm no crypto geek i'm not sure about the security caveats of the final solution:
The main questions are
Is SHA256 sufficient as a commit function?
Is the addition of the shared secret as an authentication info in the commit string safe?
What is the overall security of the 1024 bit group DH
I assume at most 2^-24 bit probability of succesful MITM attack (because of 24 bit challenge). Is this plausible?
What may be the most promising attack (besides ripping the device out off my numb, cold hands)
This is the algorithm sketch
For first time pairing, a solution proposed in "Key agreement in peer-to-peer wireless networks" (DH-SC) is implemented. I based it on a commitment derived from:
A fix "UUID" for the communicating entity/role (128 bit, sent at protocol start, before commitment)
The public DH key (192 bit private key, based on the 1024 bit Oakley group)
A 24 bit random challenge
Commit is computed using SHA256
c = sha256( UUID || DH pub || Chall)
Both parties exchange this commitment, open and transfer the plain content of the above values.
Alice Bob
ca = commit()
-------^ ca
cb = commit()
cb ^-----------
open
---^ DH pub a, chall a
open
DH pub b, chall b ^---
The 24 bit random is displayed to the user for manual authentication
DH session key (128 bytes, see above) is computed
When the user opts for persistent pairing, the session key is stored with the remote UUID as a shared secret
Next time devices connect, commit is computed by additionally hashing the previous DH session key before the random challenge. For sure it is not transfered when opening.
c = sha256( UUID || DH pub || DH sess || Chall)
Now the user is not bothered authenticating when the local party can derive the same commitment using his own, stored previous DH session key. After succesful connection the new DH session key becomes the new shared secret.
As this does not exactly fit the protocols i found so far (and as such their security proofs), i'd be very interested to get an opinion from some more crypto enabled guys here. BTW. i did read about the "EKE" protocol, but i'm not sure what the extra security level is.
"Is SHA256 sufficient as a commit function?"
The use of SHA256 should be just fine. The only issue I have heard of is that it has a hash extension vulnerability. If you produce multiple hashes using the same data don't simply concat more data to the end of the data you already hashed. In your post have have the two hashes "sha256( UUID || DH pub || Chall)" and "sha256( UUID || DH pub || DH sess || Chall)". If that second one was "sha256( UUID || DH pub || Chall || DH sess)" then there would be a relation between the hash values if UUID, DH pub, and Chall were all the same values as before. You should either take care to avoid the hash extension issue or include a salt value into the data to be hashed, either by communicating the salt across the link or having differing vales for each code path.
On a side note: is it really necessary to transmit a Chall when you already have a previous session key saved and don't need to ask the user to manually confirm the challenge code?
"Is the addition of the shared secret as an authentication info in the commit string safe?"
I'm guessing you mean to ask "Is it safe to include secret information in a hash that is to be made public?" If the secret is something that is really hard to guess and would take a really long time to perform a bruteforce attack against, then yes it is safe. If the secret is something easy to guess or has only a few possible values, then no, it's not safe unless you, at the same time, include some hard to guess secret to force a potential eavesdropper to have to guess all such secrets simultaneously. For a large, effectively random number like a DH shared secret then it should be just fine.
"What is the overall security of the 1024 bit group DH"
I'm not sure if DH group 1024 is what you want to use. A key exchange that is considered to be close to being as effective as the SHA256 hash algorithm you're using would be 521 bit ECDH. The cryptographic strength of ECDH is considered to be 1/2, so if you want 256 bit security, you want 521 bit ECDH. Unfortunately, I'm not certain about the security of the many individual 521 bit ECDH groups that have been published.
"I assume at most 2^-24 bit probability of succesful MITM attack (because of 24 bit challenge). Is this plausible?"
There is more than one way perform a MITM attack. Eve will use every resource at her disposal to perform her attacks and if you are not careful she will exploit something you didn't think of. This is why peer review is necessary in cryptography.
Simply, if you make your own cryptographic solution, then it's weak.
for the little story, the VISA guys have to start again 4 times before it's became strong enough.
I'm not a security expert, but it was what my crypto teacher told us everytime.
I've come up with this possible attack, based on my understanding of the protocol, inspired by Lowe's Attack to Needham-Shroeder Public Key Protocol:
Alice wants to reconnect. Calculates its committment ca and sends to Bob. The message is captured by Mallory.
Mallory answers. She does not know the shared secret, so she invents one. Calculates cb and sends to Alice.
At this step, Alice cannot verify the shared secret yet. So she sends DHpubA and ChallA.
Mallory ignores the messages from Alice and disappears.
Now Mallory has a valid DHpubA, ChallA and the corresponding (valid) ca.
Mallory sends ca to Bob.
Bob answers with cb.
Mallory sends a valid set of DhpubA, ChallA
Bob sends his DhpubB and ChallB
Since Bob can validate Mallory's messages, she is authenticated as Alice. Obviously Mallory does not know DHprivA, se she cannot calculate the current session key, but nevertheless you have a security flaw since Bob thinks he's talking to Alice.
General advice: avoid implementing you own cryptographic solution and don't trust security reviews from anyone else than an established security firm.
If you feel that your security requirements are not satisfied by standard mainstream crypto, try stating your requirements and asking whether is there a security procotol that matches them.
That sounds OK. Not sure what you meant by "fix[ed] UUID"?
Could a rogue app access the UUID and session keys: are they stored system-wide or in a service? There is some text in the SDK that suggests that any keystore always waits for user confirmation before returning a key.

Resources