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.
The URL returned by the embedded signing url API method EnvelopeViews:createRecipient only lasts 5 minutes.
How can I get an embedded signing URL that will last longer?
The embedded signing URL time to live is only 5 minutes.
So the answer is to give your signers a customized url to your application. Then, when your signer clicks it, your application first obtains an embedded signing URL from DocuSign and then responds to the signer with a redirect to the URL.
Creating the customized URL
Create a database table in your application with columns:
ID
url_lookup_guid
account_id
envelope_id
signer_email
signer_name
signer_clientUserId
envelope_expiration_date (optional, see below)
When you want to create a unique URL for an embedded signer:
generate a guid. It will be used as the url_lookup_guid value
Create a record in the database table.
The url will be something like myapp.mycompany.com/sign/[url_lookup_guid value]
Creating the embedded signing ceremony
The user opens (GET call) the url you gave them. Eg myapp.mycompany.com/sign/1234567-1234-1234-123456789
Pull out the guid valid from the URL
Look up the record in your database
Use the other values in the record to make a call to EnvelopeViews:createRecipient
Receive the embedded signing URL response to the API call
Redirect the signer to the URL
Remove the database record or mark it as used.
Clearing old database entries
As noted above, you can delete database rows once they're used.
To clear out entries that were never used, a batch process can check the database each day for obsolete entries where the envelope has expired.
Either record the expiration date, or auto-create an insertion date
in the database. Then, once your account's default expiration time has been exceeded, make an API call to DocuSign to check that the envelope has indeed expired. (Its expiration date may have been extended.)
Notes
The URLs that you create can last as long as you wish, or until the envelope expires within DocuSign, whichever comes sooner.
The URL will enable the person to sign the envelope, so you'd probably want to include additional signer authentication from DocuSign to ensure that the signer is who they say they are.
Don't use the database's ID as the lookup key since you want to ensure that someone can't guess the ID of a record. Use a random guid as the look up key.
Your app will need an access token to make the API call to DocuSign. Since this is an autonomous task, use the OAuth JWT grant flow.
Don't create a new access token per invocation, cache the current access token.
Since it can take a couple of seconds to create the redirect URL (or more time if you need to obtain a new access token too), you might want to first return an intermediate page that shows a please stand by message and makes an Ajax call to your app to obtain the URL for the redirect.
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)
We recently integrated Docusign to our CRM. What this did was allowed us to auto send our contract to clients when they filled out a form. This worked out great, however, the template we initially used did not have our CEO's signature already signed to it, so we have ~100 contracts in Docusign which are signed by the client but not by our CEO.
In docusign, is there a way for us to electronically sign a document already signed by the client?
You have two options
Create a new document using the completed PDF
Clone the original document and start over
Documentation here
Is there a way to obtain the view document URL sent to the recipient?
I can enumerate the envelope status pulling back a multitude of URIs.
None which seem to match the URL and parameters.
If by document URL you mean the signing URL (ie. the URL token a recipient can use to sign an envelope) then no I don't believe this is possible.
URL tokens have lots of security built into them - when you generate a token it's only valid for 5 minutes and it is a one-time use, meaning if that URL is used or expired then you need to generate a new URL for that given recipient.
To help keep them even more secure if one is generated the actual link will not be saved and or returned anywhere to help prevent an attacker getting hold of it and using it before the true/intended recipient.
So as mentioned, once generated and sent there is no way to query the DocuSign system and ask for that actual URL that you've previously created. If you want to remember each URL you generate you'll have to do that through your app logic - but take note that they will only be valid for 5 mins and a one-time usage.