how to prove that someone's previous public key was really theirs? - pki

I'm in the planning stage of an open-source credit clearing system, and my idea is to use GPG keys to sign IOUs. But I'm concerned that if Bob signs an IOU he emails to Alice, then later deletes his keys, creates a new keypair and uploads his new key to keyservers, he'll be able to plausibly deny ownership of the IOU. Is there some programmatic way of proving a key once belonged to the owner of the email account that sent the signed email? My google-fu is failing me on this one.
Update: "non-repudiation" is the word I was looking for. Still researching...

Most of the time non-repudiation is achieved with cryptographic time-stamps. A time-stamp is a proof of existence of a document at a given time and is issued by a trustworthy third-party with sign the document hash along with the time at which this document was submitted.
I do not know GPG model very well but there is probably something like a certificate which binds the public key with the key owner identity. You have to time-stamp this certificate. Actually you should also time-stamp a proof that that Bob's key is not revoked. In X.509 this is achieved by time-stamping the current revocation list which proves the "not revoked" status the key.
Cryptographic time-stamp are standardized in RFC 3161
More globally you point out one of the numerous issues and complexity of advanced digital electronic signatures: non-repudiation, long-term validation, signature commitment rules... This is the main goals of AdES standards (CAdES, XAdES and PAdES)

Related

What JWT claims from Azure AD tokens can be safely used for user mappings?

We use OAuth 2.0 to obtain JWT tokens from an Azure AD. In our application, we have used the value of the 'upn' claim to identify an associated internal username.
The Azure AD Token Reference documents the upn claim as a "User Principal Name", which as far as I understand is a username following the addr-spec format (i.e. user#domain). This works well for users created within the Azure AD Tenant. To my surprise, however, the upn claim seems to be gone if the authenticated user is sync'ed from a different AD. This behavior does not seem to be documented anywhere.
Where can I find documentation on when the upn is guaranteed to be in a token?
What are reliable alternative claims that I can use instead? Preferably claims guaranteed to be of the form "user/domain", as that matches our model best. I have considered the following:
unique_name: I have only observed this to be equal to upn, but I am not sure where it comes from. Confusingly, the token reference says: This value is not guaranteed to be unique within a tenant and is designed to be used only for display purposes. (emphasis mine)
email: This too seems to be equal to upn, but again, where is it sourced from? In the management portal, I have tried putting a different value in every email related field associated with the user, but none of them seem to be propagated to this claim. It therefore appears that this field is not actually an email.
I want to be absolutely sure that our application will be able to handle all tokens issued by Azure AD, so I am hesitant to use any of the above claims unless I have some documentation that explains their actual semantics.
Where can I find documentation on when the upn is guaranteed to be in a token?
There is no such document about how this claim is guaranteed. Based on the test, it is as you mentioned that only be issued when the users is not a external user.
What are reliable alternative claims that I can use instead? Preferably claims guaranteed to be of the form "user/domain", as that matches our model best. I have considered the following:
We can use the oid claim to map the users. This claim is contains a unique identifier of an object in Azure AD. This value is immutable and cannot be reassigned or reused. Use the object ID to identify an object in queries to Azure AD.
And if you have any feedback about the Azure document, you can try to submit the feedback from Is this page is helpful? at the right bottom page to help improving the document.
While it is fairly common for a User’s UPN and primary email address to be the same thing, that isn’t guaranteed (nor is the existence of UPN as you’ve noticed). So you should operate under the assumption that UPN != email address. If you need to know the email address, you should make a Graph call and search using the oid.

IBM Connections user ids

I'm currently confused by the IDs identifying a user in Connections, and their link to the underlying LDAP directory.
So far, I identified several ids:
email: simple but not reliable as email access might have been disabled by the admin. This is particularly true for Connections cloud.
snx:userid: UUID generated by Connections, but this is the chicken and egg. To find the userid, you need to first get access to a profile document, or some data retrieved from Connections
key: also generated by Connections, but I don't get the pattern. On Greenhouse, it is yet another UUID in x-profile-key, different from the userid above. On other systems, it seems to be based on the user name.
subscriberId: The "lotuslive id" used by Connections cloud.
Can someone explain the relationship between snx:userid, key and subscriberId, on-prem and on the cloud, and what they are for? I can't find any clear documentation around it. The API doc says that some times we should pass the key, and some times the id.
Also is the LDAP directory on prem. We are querying the LDAP directory (WAS federated directory, also used by Connections) to get a list of users based on a group. But then, how can we access their Connections profiles from the LDAP result? Is their an attribute to read? We are currently using the email, but as said earlier, this will not work if email access in disabled, like in Greenhouse.
I can explain part of it. the snx:userid is an abstraction used to uniquely identify a person - even if their email changed, name changed, or any other ldap specific id changed. The snx:userid is I believe 64bit.
I thought the Key is the same as snx:userid.
SubscriberId is based on the Business Support Services long id, and includes a scope so that each environment has a unique id.
I think I described the first part of your question on the relationship.
For the second bit, we don't augment LDAP with the snx:userid.
You may want to look at User SPI and java.lang.String getExtID()
http://www-10.lotus.com/ldd/lcwiki.nsf/xpAPIViewer.xsp?lookupName=IBM+Connections+5.0+API+Documentation#action=openDocument&res_title=User_SPI_ic50&content=apicontent
Hopefully this will help clear up some of the confusion and break down their relationships and uses.
snx:userid — This is actually not “generated” by Connections, but rather is associated with an LDAP attribute that is defined during the population process. Generally it is defaulted to an LDAP attribute that is and will always be unique to a user so that it can be used to identify a user in the LDAP if other content has changed. In some cases you’ll see this as the GUID of the LDAP (the default setting on-prem), though other times you’ll see this as a different value, like on the cloud for example. The cloud has this set this to the subscriberId.
subscriberId — This is generated and based on our Business Support Services as Paul mentioned. It is used as the true unique identified for a “subscriber” (user) to the environment, since the environment is MT and users need to be scoped. This was chosen over the default GUID as a unique identifier for a variety of logistical reasons.
key — This is generated by Connections itself during the population process. It is used to define the users profile within the context of Profiles and provides Connections with the ability to associate content with a user when the users LDAP information has been altered. It provides a separation of identity and helps facilitate user content synchronization for Connections.
Unfortunately there isn't a clear cut way to perform that lookup though, especially when you take something like Connections Cloud or Greenhouse into account. They have email disabled for a variety of security reasons. Generally speaking though, the userId is the GUID for the ldap, unless it is very explicitly redefined and configured so, but again you'd really have to know the environment in order to know that information. In a nutshell I think it has to be a configuration parameter for the app per environment if email is disabled.

Authenticaton Method for Desire2Learn REST API vs SOAP

I'm hoping someone could enlighten me on the way authentication works with the new D2L REST API. From my reading and playing with the "GetStarted" example code it seems that calls are based on the "User Identity Level" and "User Acceptance".
For us, this is a bit problematic.
We haves several custom tools where a student completes an activity (outside D2L) and is given a grade. These tools are set up so that the grade provided in this manner are associated with a grade book column for a given course in our D2L instance. Currently with SOAP, we just use a privileged web services account so that when a student completed the task, the grade was automatically exported to the associated grade book column in the given course.
My understanding from the REST documentation is that it is no longer possible to use a privileged web services account, as it would have to sign in and accept the use of the tool each time. The student completing the task wouldn't have this information (nor would we want them too) and the student level of access wouldn't allow him to upgrade the grade book column so we wouldn't be able use his "User Identity" either.
The only alternative I can think of would be to store all the grades else where. Then, when appropriate, the instructor for the course would sign on and batch update the grade book using their "User Identity Level" and "User Acceptance"?
Is this correct?
For us, this is very cumbersome as we rely on own tool's authentication methods and the privileged web service accounts quite a bit.
An extra manual login is not required and there are two alternatives that I have seen used in this scenario. Both utilize the fact that the Valence authentication system uses keys and signatures. By using signatures rather than sending tokens even plaintext apis are not subject to session hijacking and as a result keys can safely remain valid for a long time. This period is typically set to 30 days, but, when applications like the one you describe are in use it is best to have no timeout. You can contact support about adjusting this timeout for your server. (Keys are still reset if passwords are reset or if they are explicitly revoked).
With long lived keys the following scenarios are possible, without the application directly receiving or storing the users password (key storage still needs to be done securely):
Instructor account context: If the application workflow already requires an instructor to activate or configure the process the userid and userkey for that instructor can be retained during the intial session and later used to submit the grades. This does not require any special accounts or elevated priveleges, but, only applies if the workflow already involves the instructor context.
Utility account context: If the application does not involve an instructor, it is possible to create a utility account that has permissions to update grades. This is often the approach already in use with D2LWS, but, with an extra step. In this scenario, the keys for the utility account are established out of band (for example the getting started sample (http://docs.valence.desire2learn.com/samples/gettingStarted.html) will display the keys). Alternately an install or config type process can be created that automatically records the keys from the utility account. After these keys are recorded no additional interactive sessions are required.

How to encrypt a password traveling across TCP?

In my game app, running from iPhone/iPad to a central server that I control via TCP, I need to send login information.
What I currently do is send a LOGIN opcode with ascii bytes for login and password in the clear. I don't want to send user's passwords in the clear - they could be on a wifi connection for example.
How can I handle encryption of this? Here are my requirements:
I don't want to use a 3rd party lib, I will if absolutely necessary. If necessary it has to be BSD license or similar
What's the impact of me answering "yes" on "does your App have cryptography in it" to the App store
I want this app to be available in every country
Is it acceptable to, locally on the device, hash the password, and send that cached value only? The user's account could be compromised by the hash being stolen, but the password wouldn't be lost (and I wouldn't be storing their passwords)..
I can't have some kind of OAuth out-of-the-app setup system done as I've experienced before, it's too invasive
I'm sort of at a loss here. I appreciate any good help here as this is one of the last 3 things I need to address before ending almost a year of development.. (so this isn't theoretical or premature optimizing! it has grown in to an actual issue..)
First, the obligatory: "Don't invent your own password scheme. If you aren't an expert, you will do it wrong. If you are an expert, you will do it wrong in a creative way that is horribly broken but which brokenness will be invisible until your scheme is in use by thousands"
Next, be clear about what you want to protect, and why. You mention plaintext user passwords being bad for some reason. Are you concerned that a password the user uses in a bunch of places will be leaked by your application, compromising the user's other accounts, or are you more concerned that the attacker will be able to gain access to your user's account?
My concern with what I read in the subtext of your hashing idea is that the hash that the client sends will never change (unless the password changes). This makes it a plaintext-equivalent for authentication (the attacker need only steal the hash; they can then authenticate without knowing the password). It also makes the password a little more vulnerable to brute-force attacks by someone who can see the hash.
I get the impression that you want to avoid encryption for concerns that it will limit the availability of your application. I can understand that reason.
Let's assume that a cryptographically secure hash isn't cryptography (and I don't know if it is or not, but it isn't in terms of U.S. export restrictions as far as I have read). My suggestion would be a very simple challenge-response protocol to use to verify that the user has the password (I recommend you look up "challenge-response protocol" online).
One caveat here is that I don't address getting the password to the server in the first place; just the server verifying that the user has the correct password for the account. Think of this as a general idea of how you might prevent things like replay attacks, and make life more difficult for attackers that can see the data stream:
Client: "I wish to authenticate as John Smith"
Server: "Okay 'John Smith'-claiming-person, take the current date and time (2011-09-09#12:04:33AM) and a random number I just thought up: 4bazillion, and hash them with your password. Let me know what you got."
Client:
prompts user for password
hashes
Says: "I got: gaAGRtcq4qt22332."
Server:
takes date and time and random number and hashes with password
compares data from client with calculated data
If there is a match:
Says: "Okay, you're in."
Otherwise:
Says: "Go pound sand."
TLS/SSL. Just use it. It is built into iOS.
As for encryption, yes, you will need to claim you use encryption, which will require you to get an (easy) online registration certificate from the government.
Authenticate with your service over HTTPs. You will not need to use any third party libraries. You can implement this as either a post or a get.

Maintaining message integrity

I have a message that I am passing to myself which will be subject to man-in-the-middle attacks. Because of that, I am concerned about the integrity of the message being maintained between the time I send it, and the time that I receive it back.
It should be assumed that once I send the message to myself, no information about the message sent will be available to me in the future. The message is completely self-contained.
To that end, I know that should hash the message contents and compare the hashes before I send the message, and after I send the message, if they differ, then the message has been tampered with.
Of course, if the man-in-the-middle knows that the hash is really just the hash of the message contents, as-is, then because the message is self-contained, he can just create new contents and apply the same hash algorithm to the contents.
The question is, to what lengths should I go to randomize the message contents when generating the hash? When does it reach the point of diminishing returns?
In this scenario, I have a set of key/value pairs. To that end, the steps that I know I HAVE to take are:
Add a salt to the message. The salt is a secret to the rest of the world. It gets attached to the contents of the message before hashing.
Order the key/value pairs in a consistent manner before generating the hash.
While not directly relevant, a timestamp is going to be added to the contents of each message before hashing, to prevent replay attacks.
These are the optional steps that I am considering:
Transforming the keys before I order them. I've considered reversing them, then ordering by count/key.
Playing with the separators that separate key/value pairs (both for the separator for the key/value and the separator for the pair).
NOTE
Message privacy is not a requirement here, so I am not looking for encryption. The values must be transmitted in plain-text.
Finally, what hashing algorithms should I avoid?
Specifics
I have an ASP.NET MVC site which I have a controller which handles input validation and persistence.
If (based on a heuristic, it's not important which) the input is determined to be an automated spam attempt, a model of IDictionary<string, string> is created with the input values and a ViewResult is sent to a general CAPTCHA page.
In that view, in the form that contains the CAPTCHA control, the contents of the IDictionary<string, string> will be written out in hidden input fields, and the action of the form will be the same action that the contents were originally posted to. This way, MVC can pick up the values when the form is resubmitted.
It's because of this I can't encrypt the key/value pairs (or maybe I can and should, tell me why and how!).
Of course, I need to add one more value, which contains the hashed message contents. If that value is there, then the controller will check to see that the message integrity is maintained, and allow the input to be persisted if it has.
Solution
I've opted to go with the SignedCms class in the System.Security.Cyrptography.Pkcs namespace, which represents the signging and verifying of CMS/PKCS #7 messages.
To elaborate, I've created a self-issued certificate with MAKECERT.EXE and then in my code, I use the example here to digitally sign the data:
http://blogs.msdn.com/shawnfa/archive/2006/02/27/539990.aspx
Now, it should be a matter of keeping the password on the exported private key secure, as well as security on the server, which makes it less about programming.
I'll have to add an extra key for the timestamp for replay attacks, but that won't be too hard.
The answer goes to Kalium, not for his initial post, but for his follow up comments which pointed the way to digital signatures, and eventually my discovery of how to utilize them in .NET.
Thanks to everyone who contributed.
I think PGP/GPG is what you want here.
The most straight forward approach to allow your application to verify that its own messages have not been tampered with would be to use a keyed hash message authentication code. The message is sent in the clear, but it also includes a hash to prevent tampering. The hash depends on both the message contents and a secret key. The man in the middle can't forge a hash on an altered message without knowing the key. Since your application both creates and verifies the messages, it never needs to disclose the secret key.
I would particularly recommend the implementation described in RFC-2104 http://www.ietf.org/rfc/rfc2104.txt as it has been carefully thought through to avoid most of the likely pitfalls.
If the messages must also be verified for authenticity by untrusted parties, then you should use a digital signature scheme instead.
There is likely some support for both in the .Net libraries. Miles helpfully provided (as a comment) a link to the MSDN web page for the .Net library functions implementing a keyed HMACs using the SHA1 hash: http://msdn.microsoft.com/en-us/library/system.security.cryptography.hmacsha1.aspx.
You want a Digitally Signed message. Using GPG you can sign the message without encrypting it. But no one will be able to tamper with it, because they can't generate the hash - only you can because the hash uses your private key.
You should probably digitally sign the message (hence PGP/GPG recommended by Kalium is relevant as an option). Any pure hash that you can create can be recreated by the attacker. Digital signing - using your private signing key so that your public key can be used to verify it - is the solution. Anything else is an exercise in futility.
Assuming that you can't pass any information over a "secure" channel (i.e. the hash) here's how you would do it:
Hash the message, then sign the hash with a private key. Include the signed hash in the message.
When you get the message, use the public key to decrypt the signed hash and verify that it matches the actual hash of the message.
An attacker would not be able to "fake" a message, since they would need to have your private key in order to encrypt their new hash.
As others have mentioned, this is just plain vanilla digital signing and can be handled by something like PGP/GPG

Resources