Information to be kept for non-repudiation? - x509certificate

I'm using Java applet to sign XML files in a web browser.
what information, in addition to X509 key which is included in signed XML, should I keep to ensure non-repudiation?
I have seen applets transferring private key (encrypted using same private key) or just public key.

In XMLDsig/XAdES signature, the non-repudiation (proof of the integrity and origin of data) is provided by the signature itself.
The integrity is provided because if you change any bytes of the signature you will broke it (the signature can't validate), and the origin of data is provided by the <xmldsig:keyInfo> element which provides you the necessary certificate to validate the signature (however this element it's optional, so if it's not present it's supposed that application context it's enough to get that certificate), if the signature validate with this certificate you've the identity of the signature author. Besides in XAdES standard is defined the <xades:SigningCertificate> attribute which is mandatory and also it references the necessary certificate to validate the signature.
Hope this helps,

You should never transfer a private key except possibly for backup. The safest method of keeping a private key safe is to create a key pair at the location where the private key is required and then transfer the public key using a certificate request.
To verify and validate a certificate, and therefore a signature, you need the following things:
A chain of certificates that starts with the certificate of the key pair used for the signature, up to some trusted certificate. The chain can exist of 1 self signed certificate, but usually it's longer. Usually you trust some root certificate, have 1 or 2 CA certificates, ending with the leaf certificate that performs the signing.
Some method of verifying that any of the certificates in the chain was not revoked. Usually this is a frequently distributed CRL or OCSP.
A clock. Without a trusted clock it is not possibly to verify if the certificate has expire.
These are all required for verification. For signing, you don't have to keep anything. Of course, you normally hold on to your private key and certificate.

Related

Share Public Key between two devices over network [RSA]

I am working with Asymmetric Cryptography (RSA & ECC). I have a very fundamental question when it comes to public key exchange or at least my understanding of the mechanism.
Considerations
client called C1
server called S1
algorithm: RSA (asymmetric)
threat: Man in the Middle
objective: transfer of sensitive information over the network (can be data or symmetric keys for hybrid encription)
What I've read so far
C1 creates a pair of RSA keys and makes an API call sending in the public key to S1.
On getting a request with the client's public key the server (S1) generates a RSA key pair and sends it back to the client (C1).
Now that the key's have now been transferred, C1 encrypts the data (cipher text) using the server's public key, sign's the cipher text with client's private key and makes an API call.
The server receives the request that contains the cipher text, uses the client's public key to validate signature, uses the server private key to decrypt the data, performs some operations, generates the response, encrypts the response using the client's public key, signs the response cipher text with server private key and returns the response.
How can the Man in The Middle Attack is possible?
in the initial call, let's say the hacker intercepts the first call that the client (C1) makes, generates a RSA key pair and sends the server the Hacker's public key instead.
The server returns back the server public key and the hacker intercepts the server response and stores the server's public key and then returns hacker's public key to the client.
The client assumes the Hacker's public key is in fact the server's public key, encrypts the data, signs it and sends it back.
The hacker intercepts that call as well and it decrypts the data, modifies it and encrypts it with the server public key, signs it with Hacker's private key and sends it to the server.
The server verifies the cipher text and tries to decrypt it and it all works since the server has hacker's public registered as the client's public key.
Now this out to be very easy to crack, the hacker (Man in the Middle) can read sensitive information and can also modify the request that can lead to malicious operations on the application server.
I am sure I am missing something in this flow since RSA and such interaction is so widely used. Can someone please point out what have I missed and if I haven't missed out anything, how can I protect the system against such attacks

X.509 Self Signed Certificates

I'm trying to understand more about X.509 Digital Certificates. There seems to be lots of contradiction around. I am using Bouncy Castle to generate a key pair, using
public static void SaveToFile(X509Certificate newCert, AsymmetricCipherKeyPair kp, string filePath, string certAlias, string password)
{
var newStore = new Pkcs12Store();
var certEntry = new X509CertificateEntry(newCert);
newStore.SetCertificateEntry(certAlias, certEntry);
newStore.SetKeyEntry(certAlias,
new AsymmetricKeyEntry(kp.Private), new[] { certEntry });
using (var certFile = File.Create(filePath))
newStore.Save(certFile, password.ToCharArray(), new SecureRandom(new CryptoApiRandomGenerator()));
}
This saves the generated certificate to disk. Some articles tell us there is no need to password protect the certificate as there is no PRIVATE KEY stored in there. Then this article says the certificate does indeed contain the PRIVATE KEY.
I guess I have two questions that will hopefully help me understand this:
If I generate my keys in this way, should the password be the SAME as the passphrase for the PRIVATE KEY?
Do I distribute the X.509 certificate to prove the PUBLIC KEY is mine (being paired to my name in the certificate) or should the certificate be kept as safe and secret as the PRIVATE KEY and what use is a self-signed certificate?
A PKCS#12 file can contain both the certificate and the private key. They are, however, stored as separate, distinct objects. The certificate itself has the public key embedded within it. Since the certificate only contains the public key, it is considered "public" as well. You can feel free to distribute the certificate, as it does not contain the private key, which should be kept confidential. This is the basis of the security in asymmetric cryptography.
Because a PKCS#12 file contains both items, it is encrypted with a password to protect the private key within it. That said, you would use the private key to prove that the certificate you distribute belongs to you. For example, through the use of a digital signature on a document.
Hope that helps!
Certificate is actually the block of information which binds your identity (i.e. your name, email, whatever else) to some public key. It is public so everyone can know that this key belongs to you.
So when you will sign something they will know that actually you signed this.
The other thing is validating certificate - that's for what trusted root certificates are used.
Private key is your own secret information, and MUST be kept secret.

Passing signature public key along with the signature

Can anybody explain me a sense of passing a public key along with signature which is practiced in SAML 2.0? As I know signature is needed to make sure the message was not intercepted by someone, so I need to make sure the public key I'm validating the signature with is pertained to the sender, which in case of in SAML 2.0 I can get with metadata beforehand. However if I take a public key from the message in run-time, how can I know it is not intercepted and other interceptor's public key is included?
You not only want to validate that the public key matches the signature, you also want to validate that the public key itself is valid. This is generally done through a certificate chain, where each certificate in the chain is basically a signed public key. You need to ensure that each certificate is valid (has not expired, has not been revoked) and that you trust the signers of each certificate. Be careful who you trust and pay attention to revocation.

How to created signed AuthNRequest?

I am interfacing with an IDP and have a basic AuthNRequest created as follows:
<samlp:AuthnRequest
xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="IDTest1"
Version="2.0"
IssueInstant="2013-03-04T09:21:59"
AssertionConsumerServiceIndex="0"
AttributeConsumingServiceIndex="0">
<saml:Issuer>https://myapp.com/saml2/sp</saml:Issuer>
<samlp:NameIDPolicy
AllowCreate="true"
Format="urn:oasis:names:tc:SAML:2.0:nameid-format:transient"/>
</samlp:AuthnRequest>
IDP wants me send the request as signed. My questions are:
How do I set digest value?
How do I set Signature value?
For x509 certificate, I set the public key of my app. Correct?
What is the data that is used to compute any of the values? Is it my original auth request without Signature element?
Just to note that a lot of this is covered in the documentation:
SAML metadata.
To have the request signed you need to add something like this (normally found in the sp.xml):
<SPSSODescriptor AuthnRequestsSigned="true" WantAssertionsSigned="false"
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
The signing key would look something like:
<KeyDescriptor use="signing">
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<ds:X509Data>
<ds:X509Certificate>
MIIDWTC...CAkGgAwIBAgIEe+a+/uaSZCp5g2z+hRWRV+DyfQc9nO
</ds:X509Certificate>
</ds:X509Data>
</ds:KeyInfo>
</KeyDescriptor>
where the MII... is the public key.
As per #Stefan, it's much easier to use a library.
SAML Authentication Request is an XML document. You can sign SAML Authentication Request just like signing any other XML document. There are, however, some restrictions:
The signature must be enveloped signature.
Before it is digested, the SAML Authentication Request must not be transformed by method other than enveloped signature transform and exclusive canonicalization transform.
The Signature element must contain only one Reference element.
The URI of the only Reference element must contain the value of the ID attribute of the signed SAML Authentication Request.
Before it is signed, the SignedInfo element must be canonicalize using exclusive canonicalization method.
You can read more detail the SAML Assertions and Protocols Specification (http://docs.oasis-open.org/security/saml/v2.0/saml-core-2.0-os.pdf) in Section 5.
Your question is inadequate!
The AuthRequest you're sending seems to be REDIRECT request where you will not see Digest, Signature and Certificate since all these details will be in URL as a parameter.
Try using POST SSO request, where you will see Digest, Signature and Certificate in SAML request.
Some of the points:
Common
Both IdP and SP should share their Metadata, which will have their basic configuration like id, signing algorithm, hashing method, public key etc.
So, based on the contract between IdP you should hash and sign your request in your preferred programming language.
SP:
You should encrypt using your public key.
You should sign using your private key.
You should encode your request using Base64.
IdP:
They will identity using the public key in the request.
They will respond back with encrypted and signed XML.
You should decrypt and unsign the response.
Quick Links
Official Doc about SAML 2.0
SAML Online Tool by OneLogin
If your into constructing your own requests without any bigger frameworks around I can recommend OpenSAML. Its a library to help with the construction of SAML messages.
In my book, A Guide to OpenSAML, this and more is explained in detail.
EDIT I have released a new edition of the book, covering OpenSAML V3
Here is an example I wrote on signing SAML messages
And one on how to dispatch AuthnRequests.
Well things concerning security are never easy...
you sholud definetly check documentation Linked by #nzpcmad, as well as
SAML2 profiles (look for WB SSO - Web Browser Single Sign On).
For Java OpenSaml is indeed one of easiest solutions.
A pitfall seems to be that with HTTP-Redirect Binding the Signature is transported by additional URL-Parameters and not part of the SAMLRequest value, e.g. https://my-idp.com/login?SAMLRequest=nVNN...%3D&SigAlg=http%3A%2F%2Fwww.w3.org%2F2001%2F04%2Fxmldsig-more%23rsa-sha256&Signature=QZ64...%3D%3D

HMAC and WCF Service .net

So I'm very new with HMAC authentication and I really don't know what I'm doing nor reading atm.
I've been trying to understand the following articles / links / discussions properly:
How to implement HMAC Authentication in a RESTful WCF API
http://blogs.microsoft.co.il/blogs/itai/archive/2009/02/22/how-to-implement-hmac-authentication-on-a-restful-wcf-service.aspx
http://buchananweb.co.uk/security01.aspx
With that said I have a few questions:
Understanding the first link, if for example I have a loginAuthentication service created in .net and will be accessed from an iPhone app do I pass an unencrypted username (message) for this and should return just a true / false or should it return an encrypted string in which I will be using later on for other transactions (Delete, Insert services, etc)?
[ServiceContract]
public partial class LoginService
{
[OperationContract]
bool Authenticate(string username) {
// stuffs
}
}
With that said, after I verified the user, and this is where I get lost. Is it better that I save something in the database 'with a timestamp' (someone told me about this and I read some discussions about this too)? Or do I just return it with the encrypted message (dependent on the first question) so that everytime a request is made the timestamp is already attached?
a. And what do I do with that timestamp?
b. Is it going to be used once the message is sent again for another transaction?
Keys and secret message. The way I understood it is that the key will be the password of the user. So if the user sends his username I can open the message using the password of that user? This makes sense if the user already has a session and is just requesting to get data or requesting for a delete, insert, etc. Should it still be the same way if it's just authenticating the username and password of the user?
Thank you for your time!
The first thing I would like to mention is that the WCF Web Api was a beta project which is no longer being developed. It was replaced by ASP.NET Web API which is an awesome framework for developing RESTful services.
If you want to get a good idea how a RESTful service and authentication works the Netflix API would be a great place to start. They have a lot of documentation regarding the security portion and this helped me understand HMAC a lot more.
HMAC creates a hash using a secret key. The client and server both maintain a copy of the secret key so that they can generate matching hashes. This allows you to 'sign' a request which serves as both authentication (you know the person sending it is who they say they are), and message integrity (knowing the message they sent is the original message and has not been tampered with).
A signature is created by combining
1. Timestamp (unix epoc is the easiest to send in urls)
2. Nonce (a random number that can never be used twice to protect against someone re-using it)
3. Message (for a GET request this would be the URL, a POST would be the whole body)
4. Signature (the three previous items combined and hashed using the secret key)
Each of the above can be sent in the query string of the request, then the server can use the first 3 and their copy of the secret key to recreate the signature. If the signatures match then all is good.
In a RESTful API that is over plain HTTP (not using HTTPS over an ssl), I would sign every request sent because again this authenticates and provides message integrity. Otherwise if you just send an authentication token you know the user is authenticated but how do you know the message was not tampered with if you do not have a Message Digest (the HMAC hash) to compare with?
An easy way to implement the server-side checking of the signature is to override OnAuthorization for System.Web.Http.AuthorizeAttribute (Make sure not to use Mvc autorize attribute). Have it rebuild the signature just as you did on the client side using their secret key, and if it does not match you can return a 401. Then you can decorate all controllers that require authentication with your new authorize attribute.
Hopefully this helps clear up some of your confusion and does not muddy the water even further. I can provide some more concrete examples later if you need.
References:
Netflix Api Docs: http://developer.netflix.com/docs/Security#0_18325 (go down to the part about creating signatures, they also have a link which shows a full .NET example for creating the HMAC signature)
.NET class for creating HMAC signatures http://oauth.googlecode.com/svn/code/csharp/OAuthBase.cs
Netflix API Wrapper I wrote: https://bitbucket.org/despertar1318/netflix-api/overview
ASP.NET Web API: http://www.asp.net/web-api
Looking at your questions in turn
...do I pass an unencrypted username (message) for this and should return just a true / false or should it return an encrypted string in which I will be using later on for other transactions (Delete, Insert services, etc)?
If you just returned a boolean, you'd have no way to then match the authentication request to subsequent requests. You'll need to return some sort of authentication indicator, on a classic website this would be the session cookie, in your instance you want to pass a value that will act as shared key.
Is it better that I save something in the database 'with a timestamp'? Or do I just return it with the encrypted message so that everytime a request is made the timestamp is already attached?
Back to the session analogy, you want to store the key from question one somewhere (the database?) with a timestamp that indicates the life of the session/validity of the key. If it's forever then I wouldn't bother with the timestamp, if it's anything else you'll need something to say when it expires.
The way I understood it is that the key will be the password of the user. So if the user sends his username I can open the message using the password of that user? This makes sense if the user already has a session and is just requesting to get data or requesting for a delete, insert, etc. Should it still be the same way if it's just authenticating the username and password of the user?
This is where the HMACing happens. You have your shared secret, you have a message, this is how I usually combine it all together.
Use all of the message as the body of data to be hashed (that way you can be sure that someone's not just copied the hash and part of the message). Hash the body of the message using the key we shared in step one. You could salt this if wanted, I'd use the username.
Finally make sure the message contains a timestamp (UTC preferably), this way you can help prevent replaying the message later. The service that's responding to the message can compare the timestamp to what it thinks the time is. If it falls outside given bounds, fail the message. Because the timestamp will be part of the HMAC, someone can't just update the date and replay the message, the hashes won't match as soon as the message is tampered with.

Resources