From the docs:
Stripe can optionally sign the webhook events it sends to your endpoints by including a signature in each event’s Stripe-Signature header. This allows you to verify that the events were sent by Stripe, not by a third party. You can verify signatures either using our official libraries, or manually using your own solution.
Before you can verify signatures, you need to retrieve your endpoint’s secret from your Dashboard’s Webhooks settings. Select an endpoint that you want to obtain the secret for, then click the Click to reveal button.
The last paragraph suggests that the secret is truly something to be treated confidentially. Is there a reason why Stripe doesn't use a private-public key scheme for signing webhook events?
They could keep the private key in their DB, never displaying it on the UI. The UI would only show the public key. Every request made to a webhook by Stripe would be signed with the private key and verified at the receiving end with the public key. This way, malicious actors getting access to the public key would be irrelevant, as they could only use it for verification, whereas now — I assume — an accidentally revealed secret can be used for forgery.
I'm neither a Stripe employee nor a Stripe expert, but I think your question comes from an ideal world where HMAC has disadvantages compared to digital signature from the point of view you're standing on. I suppose the main reason behind this decision is the computational complexity. But for the sake of truth, why you don't consider this problem along with related factors? Stripe prevents replay attacks and publish their ip adresses. Taken together, these measures provide very real protection against message forgery.
I am just starting Hyperledger Fabric. I was reading about PKI concept in Hyperledger fabric.I am reading form this link
Below is the diagram they explain Marry uses her private key to sign the document. But in general its is explain in this link
that public key is used for encryption.
So which key is used for encryption ?
There are various aspects to Asymmetric Cryptography. A confidential message can be encrypted and disseminated over the network in various ways. Let's assume there are two participants in the network - A and B, each of them have registered themselves with a certificate authority and have obtained their crypto pair - a public key and a private key. Now, if A wants to send a message to B, he has two options
encrypt the message M using his private key and send. Now, if B has
access to A's public key over the network, he will be able to
decrypt the message. Now, assuming A's public key is generally
available over the consortium network, people other than B also will
have access to A's public key. Now, does this compromise the message
integrity? Well, no. This is because the encryption is a function of
the private key as well as the message, so people having the right
access can decrypt and see the message but will not be able to
tamper it unless A's private key is compromised.
Another way in which A can send message to B, is by encrypting it
with B's public key. Now, this message can only be decrypted only by
B and whoever B chooses to share his private key with in a secure
manner. Here, again the encryption will be a function of B's public
key and the message - that said the integrity of message can be
assured.
Hyperledger Fabric follows the first method - the messages are encrypted by sender's private key and recipient's access to the sender's public key or to the message per say is managed by by consortium/organization's membership, access control rules and channel policies.
The problem
I'm working on a mobile application where user A should physically delivery something to user B, and the user A MUST prove that delivered it.
There is a restriction:
User A or User B might be offline on the delivery, so it can not rely on internet connection
My approach
I thought about using cryptography to solve this problem:
When the delivery is scheduled, the following process occurs:
A key-pair is generated, and stored on database.
The private key belongs to User B and should be transfere to his mobile app.
Some well-known+delivery_uuid string is encrypted using the public key, and transferred to the User A.
User A is oriented to only show the encrypted code (in form of a QRCode) if the delivery occurs.
User B is oriented to read the QRCode using the mobile app when delivering.
Since the encrypted message begins with a well-known string, the User B mobile app can decrypt it and verify that the message is OK. The application store the delivery_uuid part if valid, and sends to server-side to keep track as soon as user get internet access.
If the User B try to fake the delivery_uuid, it will obviously not match.
If the User A try to fake the QRCode, the User B's app will not be able to validate the message.
Concerns
The fact of a well-known piece be present on every encrypted message can make it weaker? Considering that the key-pair is used just once.
The public key should NOT be visible to anyone. Only the back-end must use it to create the delivery proof message. Same obviously apply to the delivery_uuid
Sh*t happens. If the user B mobile app somehow crashes and loose the delivery_uuid before sending it to back-end, the user B will need to rely on user A honesty.
How strong must my keys be? Considering the monetary value of the package is low. Is RSA the better encryptation in this case?
I really know that this question is complex, but I really appreciate if someone can help-me with it.
Note: I'm not sure that Stackoverflow is the right stackexchange community to ask about this, please comment if it's offtopic. But since it have something about logic, I think that's the right place.
Seems a little complicated. Why not
UserB (and every user who installs the app to receive deliveries) is issued a public/private key pair. The private key is held only by UserB; if it is lost, a new pair can be issued. Meanwhile, the public key is public, and is stored in a database along with UserB's identity.
Upon receipt of the delivery, UserB generates a simple text document containing the date and time, the QRCode, the name of the person receiving the package, or whatever information is needed. The document also contains the public key. Any format will do.
UserB signs the document with his private key and appends the signature to the end of the document. Now you have a cleartext document spelling out everything that happened, and proof that UserB agreed to it.
UserB shares the document with UserA, and/or uploads it anywhere that is needed, e.g. system of record. Both UserA and UserB can keep an offline copy.
If proof of delivery is ever needed, UserA just needs to produce the signed document.
If I understand the problem correctly, there are three parties here :
The verifying party, which is your back-end.
The selling party, which is User A.
The buying party, which is User B.
Also I do not buy the idea that "The public key should NOT be visible to anyone". They are meant to be, that's why they are called public.
Now, In order to make sure that the item was delivered
By User A
To User B,
We can have the following setup.
The verifying party ( i.e. the backend ) generates a token, associates it with the buyer, the seller, item and persists the info.
The verifying party encrypts the token with User A's ( seller ) public key.
The verifying party encrypts the already encrypted token with User B's ( buyer ) public key.
The verifying party sends the double encrypted token along to User B. Since it has been encrypted with User B's public key, only User B can read it.
User B decrypts the double encrypted token using his private key and saves the result in his device. The result is now encrypted with User A's public key, which means only User A can read it.
When User A comes to deliver the item, User B hands over the encrypted token as acknowledgement. This can be done via a QR code scan.
User A decrypts the encrypted token with his private key and keeps it in the device.
Whenever it is feasible ( in terms of availability of internet ) to prove it to the back-end, User A encrypts the token with the backend's public key and sends it along to the back-end.
The back-end decrypts the encrypted token with its private key and does a lookup in its persistence store, matches the buyer and the seller and completes the verification.
Use signatures and not encryption.
0) The app, as distributed, contains the public portion of a keypair only the server knows.
1) Every user that installs the app generates a keypair, keeping the private key, and uploading the public key to a database.
2) When a delivery is scheduled, the server generates a delivery ID and creates a message containing:
The Delivery ID
The deliverer's (user A's) public key fingerprint.
The recipient's (user B's) public key fingerprint.
A will receive this message and signature prior to making delivery. B can, but need not receive it prior to delivery.
3) When A meets B, A can off-line transfer the message and signature to B. QR code would be difficult, depending on key size, but NFC would certainly work. B can verify the server signature and know that the message has not been falsified or tampered with. A can transfer his public key to B and B can verify its fingerprint via the signed message. A can prove he is who he says he is by creating a signature with the private key belonging to the public key that was just transferred and verified.
4) B can prove who he is by creating a signature with the public key matching the fingerprint in the delivery message. B would have to transfer his public key to A if A didn't already have it, and A can verify it matches the fingerprint stored in the message.
5) B can certify receipt by creating a signature on a message saying so (however you want to format that) and off-line delivering it to A. A can then present this to the server, which the server can verify because it has B's public key.
Let's assume that:
- A has a key pair.
- B holds a delivery UUID.
The goal is to enable B to provide a proof that only A can provide.
As previous answers this can be solved by digital signature. You should let B and A to enchange the necessary information. B should provide the delivery Id, and A must sign it.
You need to hold the public keys of the partners.
You need to provide a way for the information exchange, bluetooth perhaps?
I believe that you may need more than this simple protocol.
After reading the answers, I've formulated a solution to the problem. I'm posting it as answer to know from everyone comments about it validity.
First, let give names to the actors to simplify:
User A is the Seller
User B is the Buyer
The use case
The buyer decides to buy, and make the payment. Now he talk with the seller to combine the delivery.
After payment confirmed, the back-end generates an UUID , and associate it with that transaction_id. Let's call it delivery_uuid. By the business logic, only the buyer have access to it.
The buyer app requests the delivery_uuid to the back-end, which produce a message containing both the delivery_uuid and the transaction_id, then digitally sign this message. Lets call this delivery secret
The buyer app will keep this message in storage.
When both seller and buyer meet, and the buyer checks if the product is OK, then he gives the delivery secret, using a QRCode or NFC.
With the delivery secret in hands, the seller's app can check the delivery secret authenticity (using the application's public key), then store it to send to back-end as proof of delivery as soon as he have internet access.
Now that the back-end have the proof of delivery, the payment to the seller is made.
Considerations
Buyer signature to the message
I think that it's not necessary, since by the back-end conception, only the buyer have access to the delivery secret. If the delivery secret leaked, certainly I'm in a bigger trouble.
Seller signature to the message
Also not necessary, the only concern about the seller is that he needs to send the delivery secret to the back-end. If he loose the cellphone, that's not our problem. If the application crashes and the delivery secret is lost, then we have a problem.
Server signature
This signature allow the seller to make sure that the delivery secret
Belongs to the right transaction, preventing the the buyer to use an authentic delivery token from another transaction.
Have a valid delivery_uuid
Make sure that delivery secret is still valid (we may add a validity to it)
I have a web app which I use to collect some information from a user (not name or email) and then plan on having them electronically sign a document via DocuSign immediately online (not via email).
In order to get a signing url (aka recipient view), it appears I have to provide a definition of a recipient. Part of the definition of a "recipient" is a username and email address. Is this true?
Does the DocuSign API/SDK require me to provide an end-user's (aka signer) name and email address? It seems like the API/SDK will always return a validation error if I don't provide these things. What if I don't have that information?
You need to provide the signer's name and their client_user_id within your app. You also need to supply an email for them.
The client_user_id must be unique per signer.
If you have the signer's email, use it.
If you don't, use a unique email address that includes the client_user_id to guarantee uniqueness. Eg noreply_{client_user_id} #your_company.com
Added
Re comments:
Yes, an email address is required by DocuSign to generate an embedded signing ceremony. But it is okay to fake one (that includes your app's client_user_id for the signer) if you don't, in fact, have the signer's email.
Re: Why is this the case? Because the email and name are used by DocuSign to index the "captive signer" (someone who signs your account's envelopes but doesn't have their own account with DocuSign). That's why a fake email must be unique to this person.
This technique of using name + email to identify people enables DocuSign to, for example, not require the signer to agree to the consumer agreement to use eSignatures on second and subsequent document signings with your account. -- This provides a better UX.
Since it is very common for web apps to know their user's email, this is usually not a problem. But if you don't know the signer's email, then everything works fine with a fake email as described above.
Added more
Re:
please provide a source for DocuSign being Okay with fake email address in this case? I mean is it legal?
Currently this technique for providing a fake email address for embedded signing (when a real email address is not available), is not documented on the DocuSign web site. I will add it to the embedded signing recipe when I revise it in 2017.
Re legality: the important issue is how your app authenticates the signer. Email is one way. Depending on the use case, email authentication may or may not provide a strong enough assurance to the relying party (the person who receives the signed document).
But we digress. Even if you do have a person's email address, it is common to authenticate the person beyond using their email. DocuSign has many different types of additional authentication built-in and easy to use including 2FA via SMS, pre-shared secret, in-person signing (which can include in-person verification of government ID), e-notary, digital certificates, telephone authentication, knowledge based authentication, and more. Most of these can be included with embedded signing if you wish.
Or your app (which is using embedded signing) can itself authenticate the person. When someone signed up for your app, did they have to first prove their identity? That was the authentication step. If no one else can log in as them, then they're still authenticated when you give them the embedded signing ceremony from DocuSign.
Let's assume that i use a telnet session and send an email with address alice#domain.com to bob#domain.com but in fact i am charly#domain.com...
On alice#domain.com i have a WCF web service running that's monitoring that specific mailbox using Exchange Web Services...
How can i tell that the message from bob#domain.com actually came from charly#domain.com?
I am using Visual Studio 2010, with .NET 4.0 and EWS managed API 1.1
The server is configured to use SSL and i have Exchange Server 2007 SP1.
i tried the two properties "Sender" and "From" but they are identical and both point to bob...
nothing in the message header actually points to charly... everything points to bob... any ideas? things that i might have overlooked?
If you want to make sure that identity spoofing is not possible using an email service, you can use cryptographic signatures. PGP / GPG and S/MIME are common technologies in use to implement this.
This requires every mail sent from alice#domain.com to be signed by her with a secret. The key or certificate she uses to do this must be trusted by your webservice. Your webservice can verify that a mail has really been sent by Alice by checking the validity of the signature. Only someone who possesses the secret of Alice can create such a valid signature. If the signature is wrong or missing, your webservice can trigger an alert.
Should the real Alice forget to sign an email, your service will trigger as well, because it cannot tell if it really was Alice who sent that mail. You also need to make sure that the secret in use can only be accessed by Alice. If you need further informations, you should read up on public key cryptography.
I don't think you can detect such practices with EWS Managed API at least I don't see anything that could be helpful in this situation. Unless valid sender is recognized with use of some cryptographic signatures or you can somehow mark messages from valid senders with your own extended property that only you (your software) create and uses you have to believe that mail was sent by whoever is showing up in Sender or From property