Signing documents with a Cloud Identity - google-oauth

So I have a document shared between two or more users. Call them Alice and Bob.
When editing this document, Alice is signed in using OAuth with office 365 or google gsuite; I'll call that an identity provider.
When I pass this document to Bob, I want to be able for Bob to have confidence that the content written by Alice was indeed written by someone with the ability to sign in the identity provider as Alice.
The obvious way to do this is for Alice to digitally sign the changes in the document with a public/private key pair, and then connect the public key to her own identity.
This will require that Bob can get at that public part of the key through a way they can reasonably verify required that Alice put that public key there.
Also, I want the file's current location/storage/transmission to not be required to prove the identity of Alice in any way. And, ideally, I'd like Alice to be able to authenticate, disconnect from the internet, and continue to be able to make provably-authored edits on her document.
I'm afraid I'm reinventing the wheel, but I cannot find any evidence that there are pre-existing APIs for doing this. This seems like a really basic set of operations; being able to sign data with identity, and verify it was that identity that signed it. I was somewhat surprised when I couldn't find an API to do this.
Embedding a link to a shared document that Alice has on her cloud storage, and having Bob go and fetch it to verify the signature, is one thing I'm considering; is there a way to have a stable URL with both of those storage providers that can be traced back to being connected to Alice?
Is there a better approach?

Alice must get document signing certificate separately from the office 365 or gsuite. It is possible to get simple and cheap certificate that shows that this e-mail address control has been verified.
If the private key is on the HSM like Smart Card or USB token then it is possible to get eIDAS approved or Adobe Trusted list CA signed certificate and signature validation is relatively easy.
It is also possible to setup your own CA and in this case you need to implement signature validation as well and make sure your own CA is trusted by Bob

Related

Storing API key

I am building a website that’s gonna have a pay system that works with the mollie API. In particularly the website needs to send users a payment link for their ordered products. To accomplish that mollie needs to authenticate with a api key. So I need to store the api key somewhere safely.
So my idea is to use AES Symmetric Cipher encryption when the admin registers his api key (CMS). With this encryption I need only one key to decrypt and encrypt the api key. I was thinking of using the plain text password of the admin as the key, because I don’t store this value (I hash the passwords) so it’s only available when then admin types his password. So when the admin wants to send a payment to an user the website will ask his password.
So my question is: Is this is a safe way of storing the api key?
Sorry for my bad English, it's not my native language.
First. API secrets and passwords have different lifecycles (key rotation & password change policies), and possibly different complexity requirements.
Second, The admin's plaintext password shouldn't be used for anything other than signing the admin in. Don't put all your eggs in one basket - you want to limit the scope of damage in case a secret gets compromised.
You would be better off just creating a separate secret for API key encryption/decryption, and storing it in some secret management e.g. Vault, AWS secrets, etc.
If you want to avoid storing the API key altogether, and you're fine with the admin just remembering it, then you can have the admin manually enter the secret, like a second password, but in any case it would be bad practice to couple it with the admin's sign-in password.

Backend without traditional Authentication mechanism, use cryptography instead

Context: I have a mobile app, and I don't have, and will not, implement a traditional authentication flow (email/pw, social login). Instead, I would like to leverage asymmetric key encryption.
Requirements: For the sake of simplicity, let's imagine a simple backend with one User model, which only has one field: favorite_number.
a user can CRUD a User model on the backend.
a user cannot CRUD another user's User model.
Potential solution:
Alice generates a private/public key pair on her mobile device. She keeps the private key securely on-device.
Alice makes a network request (let's say a RESTful POST request) to the backend, with the following payload:
{
"public_key": {Alice's public key},
"favorite_number": 42,
"signature": sign_with_private_key(42)
}
where sign_with_private_key(42) is the signature of the message 42, signed with Alice's private key.
The backend receives the above payload, verifies that the signature matches the public key and the favorite_number, and saves the following information in its DB (assume SQL below):
| public_key | favorite_number | signature |
| ---------- | --------------- | --------- |
| 0x... | 42 | 0x.. |
Alice wants to read her favorite number:
Alice sends GET /api/get_nonce?public_key={Alice's public key} to the backend
The backend looks in the DB the row with Alice's public key, and returns its signature column ONLY
Alice decrypts the signature with her local private key, it returns 42.
Bob wants to read Alice's favorite number, he calls the same endpoint GET /api/get_nonce?public_key={Alice's public key}, get's Alice's favorite_number signature, but cannot decrypt it.
Bob wants to modify Alice's favorite number, but cannot, because he can't compute the signature of the favorite_number message.
Caveats (which I can live with):
If Alice loses her phone or uninstalls the app, all her account information on the backend will be lost.
Additional assumptions:
The DB cannot be directly accessed by other party than the backend (and DB administrator) itself. (clarification request by #kelalaka). But that's independent of authentication.
Question: Is this authentication scheme viable? Do you see any big security loopholes?
This feels a bit over-complicated. If Alice has a keypair, then Alice can simply sign requests, and the signature is the authentication. There's no particular reason to sign individual pieces of data. Just sign the requests themselves. For example:
{
"request": {"message_id":123,"public_key":"...","favorite_number":42},
"signature": signature_of('{"message_id":123,"public_key":"...","favorite_number":42}')
}
It is critical that you sign everything that is part of the request.
Note that requests need to be single-use, otherwise this is not secure. By single-use, I mean that a timestamp should be in the request and the same request should not be useable more than once. You can also use a message counter (especially since you only have one device that can connect). So the server always rejects messages ids equal to or smaller than the last id sent for this user.
Your approach is vulnerable to reuse of the value upon another key. For example, I could reuse "42" and assign it to some other thing like "hated_number." Or I could replay this message and reset Alice's favorite number to 42 after she has changed it to something else. Signing the entire request is a much better approach and avoids a number of these problems (as long as a request can't be reused).
If Alice wishes to protect the data from the administrator, then she should encrypt the data with a symmetric key, but that's independent of authentication.
A simpler way to implement this, provided the transport is trusted, is to let Alice generate a random 256-bit identifier, and simply use that as the authentication. A 256-bit identifier will always be sufficiently sparse that it is unguessable (guessing the identifier is precisely the same as guessing an AES-256 key). With that, simply knowing the identifier is sufficient to authenticate a request. This only works if the transport is trusted, but that's the same as any static credential (username+password, token, etc). By a trusted transport, I mean HTTPS with pinned certs, for example, or any similarly encrypted and authenticated transport.

Handle user login using asymmetric cryptography

Is it possible to implement a login protocol with asymetric cryptography instead of the hashed password method?
For example, while creating an account, the client generates a private/public key pair from a hash of the username and password. The public key is then sent to the server with the username, and the server stores the username and the public key. When the user wants to login, he enters his password, the client regenerates the private key, signs a nonce with it, and sends the signed message to the server. The server is then able to authenticate the user as he knows the public key associated with the username.
Is there any flaws in this protocol?
And what would be the advantages over storing the password hash?
There might be a serious flaw with the authentication, yes, depending on the implementation. If Bob is the server and Alice is the client, with Mallory a malicious eavesdropper:
If Alice generates a random number, concatenates this with her username, encrypts with her private key and sends to server. Server decrypts and verifies with Alice's public key. Without the server saving the random number, this is susceptible to replay attacks - Mallory could just listen in, save the blocks that Alice sends to the server and just replay them later. Without saving them, the server would be none the wiser.
To protect the server against this, the server would have to generate the random number. It would also need to be a secure random number, otherwise Mallory could predict, or at least guess what the next number will be.
If Mallory could intercept messages, then he can purport to be Alice - he intercepts all communications and just relays them, even if the server generates the random number.
Alice and Bob both need to be able to prove that it was the other who has cheated. They also need to be able to detect tampering from Mallory - the protocol needs some extra layers to ensure authenticity of the messages.
There is research going into this at the moment, but as far as I know, it is very difficult to authenticate a user without a trusted certificate authority also being used: public keys can be known by all, but any attacker can swap their own public key for that of another without detection, unless there is trust established through a certificate authority.

What is an etoken?

I need to write a code to check the validity of the digital certificate present in an etoken.
I am not familiar with etokens. Can anyone please answer my following questions,
How to access the digital certificate content from etoken?
Can we access the private key stored in etoken?
When we plug the etoken to an computer then does it copy the digital certificate on the computer or not? If yes then where does it copy it?
I need to write C++ program for the same. Can we use Cryptographic API's (like CrypImportKey() CryptExportKey() ) provided by Microsoft for the above requirement?
"etoken" was the name of one of first USB cryptotokens produced by Aladdin. What you are asking for is usually referred to as security token. This is a hardware device with it's own memory, in which certificates and private keys are stored.
Tokens need drivers to be installed in order to work properly. The driver set includes implementation of CSP (Cryptographic Service Provider) for CryptoAPI. CSP does the job of presenting certificates, stored in the token, to CryptoAPI. To answer your questions:
Via CryptoAPI or PKCS#11 interface (drivers for both are supplied by the vendor).
You can perform certain operations with the private key by calling the appropriate API. But the key itself is not extractable.
I can't say for sure but for me it looks like certificates are copied to in-memory certificate store for speed of operations.
In relation to your second question, I believe it is possible to access the private key on the security token. The security token had to be pre-programmed and loaded with a private key somehow. Also, the last time we renewed our certificate, we did it online, using the issuer's web interface which installed an ActiveX module that uploaded the new certificate to the device. I don't know if this procedure also uploaded a new key but possibly not, since I don't believe you need to change your private key to create a new public certificate for yourself (which needs to be signed by the issuer to be trusted I believe).
Sorry I might not make much sense as I am new to the whole idea of Public Key Infrastructure.
If someone else could validate/invalidate my claims, please share your knowledge.
EDIT: I found this hardware hack for Alladin devices: http://seclists.org/bugtraq/2000/May/48
Basically, it is possible to read the date on the eToken but it requires a direct hardware interface to the device's on-board memory.

Understanding SSL

I have three questions regarding SSL that I don't fully understand.
If I get it correctly, a server A submits a request to a certain CA. Then, it receives (after validation etc.) a digital certificate composed of a public key + identity + an encription of this information using the CA's private key.
Later on, a client B wants to open an SSL communication with A, so A sends B its digital certificate.
My question is can't B just take this certificate, thus stealing the identity A - which will allow them to authenticate as A to C, for example. I understand that C will decrypt the certificate with the CA's public key, It will then encrypt its symetric key which will only be decryptable by the real A.
However, I do not see where authentication comes to play if B can actually steal A's identity. Unless I am missing something.
Second question: Why use hashing on the certificate if a part of it is already encrypted by the CA? Doesn't this mean that no one can mess around with a digital certificate (in high probability) anyway?
If I am stackoverflow and I have 3 servers doing the same thing - allowing clients to access, read, identify etc. - do I have to have a different digital certificate for each of the 3 servers.
Thank you very much.
An SSL identity is characterized by four parts:
A private key, which is not shared with anyone.
A public key, which you can share with anyone.
The private and public key form a matched pair: anything you encrypt with one can be decrypted with the other, but you cannot decrypt something encrypted with the public key without the private key or vice versa. This is genuine mathematical magic.
Metadata attached to the public key that state who it is talking about. For a server key, this would identify the DNS name of the service that is being secured (among other things). Other data in here includes things like the intended uses (mainly used to limit the amount of damage that someone with a stolen certificate can do) and an expiry date (to limit how long a stolen certificate can be used for).
A digital signature on the combination of public key and metadata so that they can't be messed around with and so that someone else can know how much to trust the metadata. There are multiple ways to handle who does the signature:
Signing with the private key (from part 1, above); a self-signed certificate. Anyone can do this but it doesn't convey much trust (precisely because anyone can do this).
Getting a group of people who trust each other to vouch for you by signing the certificate; a web-of-trust (so called because the trust relationship is transitive and often symmetric as people sign each others certificates).
Getting a trusted third party to do the signing; a certificate authority (CA). The identity of the CA is guaranteed by another higher-level CA in a trust chain back to some root authority that “everyone” trusts (i.e., there's a list built into your SSL library, which it's possible to update at deployment time).
There's no basic technical difference between the three types of authorities above, but the nature of the trust people put in them is extremely variable. The details of why this is would require a very long answer indeed!
Items 2–4 are what comprises the digital certificate.
When the client, B, starts the SSL protocol with the server, A, the server's digital certificate is communicated to B as part of the protocol. A's private key is not sent, but because B can successfully decrypt a message sent by the other end with the public key in the digital certificate, B can know that A has the private key that matches. B can then look at the metadata in the certificate and see that the other end claims to be A, and can examine the signature to see how much to trust that assertion; if the metadata is signed by an authority that B trusts (directly or indirectly) then B can trust that the other end has A's SSL identity. If that identity is the one that they were expecting (i.e., they wanted to talk to A: in practice, this is done by comparing the DNS name in the certificate with the name that they used when looking up the server address) then they can know that they have a secured communications channel: they're good to go.
B can't impersonate A with that information though: B doesn't get A's private key and so it would all fall apart at the first stage of verification. In order for some third party to impersonate B, they need to have (at least) two of:
The private key. The owner of the identity needs to take care to stop this from happening, but it is ultimately in their hands.
A trusted authority that makes false statements. There's occasional weaknesses here — a self-signed authority is never very trustworthy, a web of trust runs into problems because trust is an awkward thing to handle transitively, and some CAs are thoroughly unscrupulous and others too inclined to not exclude the scum — but mostly this works fairly well because most parties are keen to not cause problems, often for financial reasons.
A way to poison DNS so that the target believes a different server is really the one being impersonated. Without DNSsec this is somewhat easy unfortunately, but this particular problem is being reduced.
As to your other questions…
Why use hashing on the certificate if a part of it is already encrypted by the CA? Doesn't this mean that no one can mess around with a digital certificate (in high probability) anyway?
While keys are fairly long, certificates are longer (for one thing, they include the signers public key anyway, which is typically the same length the key being signed). Hashing is part of the general algorithm for signing documents anyway because nobody wants to be restricted to signing only very short things. Given that the algorithm is required, it makes sense to use it for this purpose.
If I am stackoverflow and I have 3 servers doing the same thing - allowing clients to access, read, identify etc. - do I have to have a different digital certificate for each of the 3 servers.
If you have several servers serving the same DNS name (there's many ways to do this, one of the simplest being round-robin DNS serving) you can put the same identity on each of them. This slightly reduces security, but only very slightly; it's still one service that just happens to be implemented by multiple servers. In theory you could give each one a different identity (though with the same name) but I can't think of any good reason for actually doing it; it's more likely to worry people than the alternative.
Also note that it's possible to have a certificate for more than one service name at once. There are two mechanisms for doing this (adding alternate names to the certificate or using a wildcard in the name in the certificate) but CAs tend to charge quite a lot for signing certificates with them in.
My question is can't "B" just take this certificate, thus stealing the identity of "A" - which will allow them to authenticate as "A" to "C"
There's also a private part of the certificate that does not get transmitted (the private key). Without the private key, B cannot authenticate as A. Similarly, I know your StackOverflow username, but that doens't let me log in as you.
Why use hashing on the certificate if a part of it is already encrypted by the CA?
By doing it this way, anyone can verify that it was the CA who produced the hash, and not someone else. This proves that the certificate was produced by the CA, and thus, the "validation etc." was performed.
If I am stackoverflow and I have 3 servers doing the same thing - allowing clients to access, read, identify etc. - do I have to have a different digital certificate for each of the 3 servers.
It depends on the particular case, but you will likely have identical certificates on each.
First question: You are correct about what you get back from the CA, but you are missing part of what you need before you submit your request to the CA. You need (1) a certificate request, and (2) the corresponding private key. You do not send the private key as part of the request; you keep it secret on your server. Your signed certificate includes a copy of the corresponding public key. Before any client will believe that B "owns" the certificate, B has to prove it by using the secret key to sign a challenge sent by the client. B cannot do that without A's private key.
Second question: Typical public-key cryptography operates on fixed-size data (e.g., 2048 bits) and is somewhat computationally expensive. So in order to digitally sign an arbitrary-size document, the document is hashed down to a fixed-size block which is then encrypted with the private key.
Third question: You can use a single certificate on multiple servers; you just need the corresponding private key on all servers. (And of course the DNS name used to reach the server must match the CN in the certificate, or the client will likely balk. But having one DNS name refer to multiple servers is a common and simple means of load-balancing.)
In general, yes, if the cert file gets stolen, nothing will stop someone from installing it on their server and suddenly assuming the stolen site's identity. However, unless the thief takes over control of the original site's DNS setup, any requests for the site's URL will still go to the original server, and the thief's server will stay idle.
It's the equivalent of building an exact duplicate of the Statue of Liberty in Antarctica with the expectation of stealing away New York's tourist revenue. Unless you start hacking every single tourist guide book and history textbook to replace "New York" with Antarctica, everyone'll still go to New York to see the real statue and the thief will just have a very big, green, complete idle icicle.
However, when you get a cert from a CA, the cert is password protected and cannot simply be installed in a webserver. Some places will remove the password so the webserver can restart itself without intervention. But a secure site will keep the password in place, which means that any server restarts will kill the site until someone gets to the admin console and enters the PW to decrypt the cert.
Question N°1
can't B just take this certificate [...] which will allow them to authenticate as A to C
This part of the a larger diagram deals with that question.
Mainly : if you only have the public key then you can not establish an SSL connection with any client because you need to exchange a secret key with them and that secret key has to be encrypted using your public key, which is why the client asks for it in the first time. The client is supposed to encrypt the shared secret key with your public key and you are supposed to decrypt it using your private key. Since you don't have the private key, you can't decrypt the secret exchange key, hence you can't establish any SSL communication with any client.
Question N°2
Why use hashing on the certificate if a part of it is already
encrypted by the CA?
This is also answered in the original diagram by the question "what's a signature ?". Basically, we're hashing the whole certificate to be sure that it hasn't been tampered with (data integrity), that nobody has changed anything in it, and that what you see is really what was delivered by the CA. The diagram shows how hasing makes that possible.
Question N°3
If I am stackoverflow and I have 3 servers [...] do I have to have a
different digital certificate for each of the 3 servers.
This is not necessarily always the case. Consider the situation where all three servers are on the same domain, then you only need one certificate, if each of them is on its own subdomain you can have one single wildcard certificate installed on all of them.
On the contrary, if you have one server that hosts multiple domains you would have one single multi-domain SSL certificate.
I also have some answers.
Q1) If B steals A's certificate and try to impersonate as A to C.
C will validate the IP address of B and find out that it does not belong to C. It will then abort the SSL connection. Of course, even if C sends an encrypted message, then only the Real A will be able to decrypt it.
Q2) A certificate is usually represented in plain-text using the common format X.509. All entries are readable by anyone. The hashing process is used to digitally sign a document. Digital signing a certificate makes the end user validate that the certificate has not been altered by anyone after it was created. Hashing and encrypting the content using the issuer's private key is done to create a digital signature.