Will my tokens still be possible to validate, if I have two different certificates based on the same private key? - identityserver4

For my Identity Server 4, we have two different servers set up to host the application.
I asked our operations team to install the same certificate on the two servers. However, they both have received different thumbprints, and the values in the certifiiates are different in the following fields: kid, x5t, n and the value in the x5c chain is also different between the two, when I load the .well-known/openid-configuration/jwks address. I've posted the keys below. Will this work? I thought the values would be the same for the x5c.0 value, if they were based on the same private key.
First key:
keys
0
kty "RSA"
use "sig"
kid "8366EB61F60720FE0FCC5C0E6BF3E5F8ACC98E2DRS256"
x5t "g2brYfYHIP4PzFwOa_Pl-KzJji0"
e "AQAB"
n "6sYPa_JNapDqcw3KgvlmtbrrCuYCd1sq3R_3Ao1aAW7bHjdN1isphP8eWsCA5WeTDmDSfE1GsN2ri0pyVY8LlqAYznEyqHI1FDVS_d601TMiq_WiMTapnQQKFdw0SF1xLNWVT13QsosgErYq0g7pJvlpYDRRXymU8Arw0LMya6nD2sMbFggYEpqMdT_j7KLiZ6oC_2G5v4VVaMdZOF8ppzUkFFtj4MU4k7J_8zVM1LbCy8vH8uyjxGqCsRzbryDu-yhQmPy1FIXBX4ZZgXy8gB2bLLPtndba9rmSFMq4VbWDjwe2hqAF7X4yvru0bGeu_4mxB10vxO2KPP9Sqaniqw"
x5c
0 "MIIFvDCCA6SgAwIBAgITHQAAADE6PYCZMMXL9QAAAAAAMTANB8VHvcXFg4="
alg "RS256"
keys
0
kty "RSA"
use "sig"
kid "B2042B75C33612AC9BD31051B2821E5DEB4D0F34RS256"
x5t "sgQrdcM2Eqyb0xBRsoIeXetNDzQ"
e "AQAB"
n "zJiOYj3NhxS4vxte0GtimbMwu6DtFHISguFdlLaroRQaNciqVynyRYJ2v8y5194miwT_K3jtKnh9lSGz93Q7Z500kvmZjS9boqQFn8g-I_02FOUUcLzsJJOTcBGqt6lvja5YlVhdWKG92sq8RizkDm28GV6bdDLh8mbR6GtwyvD2iN7aHs7nE6Z-S5doFlkr4SJ9lUxNMr18WpQHqXvP3Z0lpr8E5DRVv80n5HS7u9uusZvhryOp1QgQGfikCqPc8XNcZ9GyXhtGJkHD-QlpUZVbondHZOCi5IKOUrq7LK4cgILB-zDVIGVpyl0JhhjCCp02wq9kWcgKAvTcb8m8Aw"
x5c
0 "MIIFmjCCA4KgBpvenCRU6YuvZamis9K4OrGuKNK0EwNe1tbPMViVE++/H21P/utQ=="
alg "RS256"

Why don't you use the same signing key certificate with the same private key in both installations of IdentityServer?
you also need to keep in mind that the certificate for the domain name (the server) is separate from the token signing keys.
The token signing key needs to be the same in both instances. To install the private signing key, it can be convenient to wrap it up inside a X509 certificate.
A certificate contains a private key and you can have many certificates based on the save private key. I would use openssl to generate the private signing key for the tokens and keen the domain certificate separate, just to get a clear separation of concern. If you use Azure Key Vault, you can even create and store the keys there directly.

Related

Signal Protocol X3DH "associated data" byte sequence AD i.e. Safety Number

Hey guys I have been stuck and I cannot understand the following from the Signal Protocol Documentation:
Alice then calculates an "associated data" byte sequence AD that
contains identity information for both parties:
AD = Encode(IKA) || Encode(IKB)
An initial ciphertext encrypted with some AEAD encryption scheme [4]
using AD as associated data and using an encryption key which is
either SK or the output from some cryptographic PRF keyed by SK.
I do not understand what the Encode function is or like how to write it up in C. Can it just be any encoding function of bytes and if not what encoding do I use?
Additionally, the aead encryption scheme, does this mean I will be encrypting the original message from Alice with AD and SK (Shared Key generated from the HKDF)? If so, what algorithms can I use to encrypt (I could not find any algorithms from Github)?

What is the proper way to get some specific user attributes from Active Directory via LDAP C API?

I am trying to get some user attributes from Active Directry using Windows LDAP API. I am using:
Active Directory Version: The one that comes with Windows Server 2012
LDAP version: 3
Wldap32.lib version: The one that comes with Windows 10 x64
Eg:
PCHAR myAttributes[4];
myAttributes[0] = "DistinguishedName";
myAttributes[1] = "DisplayName";
myAttributes[2] = "PasswordExpired";
myAttributes[3] = "mail";
ldap_search_s(
myLdapConnection, // Ldap connection
myDomain, // DN to start search
LDAP_SCOPE_SUBTREE, // Scope
myFilter, // Filter
myAttributes, // Retrieve list of attributes
0, // Get both attributes and values
&mySearchResult // [out] Search results
);
It returns DistinguishedName, DisplayName and mail attributes, but does not reuturn the PasswordExpired attribute.
I queried with some other attributes and it looks like it does not return attributes with boolean values as well as the EmailAddress attribute.
Why does it not return PasswordExpired attribute?
What about EmailAddress ?
Is there a difference between EmailAddress and mail ?
There is no PasswordExpired LDAP attribute in Active Directory. To build your query look at this URL for attribute names in standard Active Directory schema https://msdn.microsoft.com/en-us/library/ms675090(v=vs.85).aspx. To check if password for given account is expired you'll need to check userAccountControl attribute, which is actually value storing flags of different states of user account https://msdn.microsoft.com/en-us/library/ms680832(v=vs.85).aspx. There is IADsUser interface that will translate this all for you in case you don't have to stick just to LDAP https://msdn.microsoft.com/en-us/library/aa746343(v=vs.85).aspx
You will find current primary email address in mail attribute. There is no EmailAddress LDAP attribute, unless you meant E-mail-Addresses which is CN for the same schema attribute as mail, so no difference there.
See above. In general if you do not have compelling reason to stick just to C/LDAP I'd recommend you to use .Net Framework instead. Otherwise you have a lot of work ahead of you - not just interpreting bit flags like in case of password expiration but possibly also with different authentication methods, different structures capturing time and date, accounting for timezones, UTF, chasing referrals and other stuff you might need depending on complexity of what you want to achieve. You will be productive much faster in .Net Framework. See DirectoryServices https://msdn.microsoft.com/en-us/library/mt481534(v=vs.110).aspx namespace or Security namespace https://msdn.microsoft.com/en-us/library/mt481561(v=vs.110).aspx for details.

What's the safest encryption I can use for a user to login to my program?

I'm writing a program and before it loads I want the user to enter the correct password without storing the password anywhere in my code. I've implemented MD5 hashes before but from what I've read they're outdated and can be broken. There are a few sites out there that attempt to reverse engineer and MD5 hash. What's the strongest encryption I can use to keep prying eyes out of my program (e.g., The NSA)?
"Encryption" is not the right thing to do for storing user passwords - as by design an encrypted password can be decrypted. As you said - hashing is the way to go.
MD5 is outdated, and I believe the current recommendation is sha1.
Note that there are ways to reverse any hashing algorithm to acceptable input. The commonly accepted standard to make this much more dificult is to add a unique "salt" to all passwords before putting them through the hashing function. A common mistake made when adding salts to passwords is to use the same salt value on every password in the database.
When salting passwords, use a unique value, for example the user ID, or the created date/time string for the user record. This will prevent attacks based on rainbow tables because there will be no existing ready to use rainbow table for your stored password hashes.
I personally like the approach of using the created date / time string of the user as it's a value that should never change and will be available and will likely be different for each user the the database.
Eexamples below assume you are familiar with PHP - however the concepts can be applied to any language.
Example:
Before saving a new user into the database:
$date = date('Y-m-d H:i:s');
// save this same value into the user record somewhere
$passwordHash = sha1($user['created_date'].$_POST['password']);
// and save the $passwordHash value into the password field for that user
To authenticate a login attempt, use something like the following:
function authenticateUserLogin($email, $password) {
$user = $db->fetchRow('SELECT * FROM users WHERE email=?', array($email));
if (!$user) return false;
$passwordHash = sha1($user['created_date'].$password);
return $user['password_hash'] !== $passwordHash;
}
To update an existing users password, use something like...
$passwordHash = sha1($user['date_created'].$newPassword);
$db->query('UPDATE users set password_hash=? WHERE id = ?', array($passwordHash, $user['id']));

what are the rules that apply on the key_name in app engine?

I'm trying to use an app engine User object's user_id (returned by the User.user_id() method) as a key_name in my own User class. The problem is that it keeps telling me that it's an invalid key_name. I've tried sha2'ing it, and using the digest() as well as the hexdigest() method to reduce the number of possible characters, but still no good result. Is this because the value is too long, or because key names can't have certain characters? And also, how can I modify a user_id in such a way that it stays unique, but is also usable as a key_name for an entity? Extra bonus if it uses a hash so that thje user_id can't be guessed.
Here is the code where the error occured:
def get_current_user():
return User.get(db.Key(hashlib.sha1(users.get_current_user().user_id()).hexdigest()))
I'm now doing some more testing, concidering suggestions from the comments and answer.
I'm not sure why it isn't working for you, the following has no issues when I run it in the dev console.
from google.appengine.ext import db
from google.appengine.api import users
user = users.get_current_user()
name = user.user_id()
print db.Key.from_path ('User', name)
However if you are hashing it (which it sounds like you may be), be aware that you may get a collision. I would avoid against using a hash and would consider some other means of anonymization if you are giving the key to clients. Such as another model whose key you can give away, that has the user's key stored in it. Another method would be to encrypt the id (using the same key for all users) rather than hash it.
If you are doing something that generates binary data (encryption / hash digest) app engine (the sdk at-least) has issues, so you need to encode it first, and use that as the key_name.
name = user.user_id()
hashed_name = hashlib.sha1(name).digest()
encoded_name = base64.b64encode (name)
db.Key.from_path ('User', encoded_name)

Check if the file is correct using sha1withRsa via openssl functions

Hi, i have file_data(xml format) and file_signature(ASN1 DER), and also have certificate(X509 ASN1 DER). I want to check if file_data is correct, but I have some problems. what I'm doing:
Main Idea: Some company A creates file_data, then using SHA1 gets hash of the file_data, and encrypts this hash using RSA private key and gets file_signature. Then company A sends me file_data and file_signature and certificate. I get public key from certificate get file_signature and decrypt file_signature using public key and get hash_1. Then i get file_data and use SHA1 to get hash_2. If hash_1 and hash_2 is equal, i can trust to content of the file_data, am I right?
Implementation:
Load certificate: d2i_X509_fp() function. Now I have certificate.
Get public key of the certificate: X509_extract_key, now i have public key.
Now i want to load file_signature to decrypt it using public key, BUT file_signature has ASN1 DER format how I can load it, what function in OpenSSl should I use?
Suppose I read file_signature, now I must decrypt it using my public key, is there any API for this purpose?
Suppose I decrypt file_signature and get hash_1.
Now I must load file_data and get hash of it using SHA1 function hash_2, what function I must use? SHA1(), or SHA1_Init, SHA1_Update, SHA1_Finish?
Suppose I get hash_1 and hash_2, how i must compare them, using memcmp?
Suppose I compare them, if they are equal, i can use file_data.
another question is that file_signature is 128 byte len and when i decrypt it i get 128 byte hash_1(Am I rigth) , but when i get hash of the file_data hash_2 it's length is only 20 bytes, so how I can compare them, or I misunderstand something?
Thanks for your help!
p.s. sorry for my english;).
If you get a file_signature of 128 bytes, then it is probably not ASN.1 encoded. 128 bits is exactly the key length of a 1024 bit key (on the low side nowadays, check keylength.com). Hashes are not directly encrypted if RSA is used: first it is wrapped within an ASN.1 structure, and then it is padded, all according to PKCS#1 v1.5 (Google it).
Normally you don't perform the hashing separately from the RSA encrypt. Libraries like openssl will contain functions to perform verification where the hash is automatically calculated (no doubt this would be openssl_verify()). Those functions will also do the compare for you.
Note that you will need to establish trust for the public key, otherwise an attacker could just generate a random key pair and send you a different public key together with the attackers signed data. Normally public keys are trusted using direct communication beforehand, or using a PKI infrastructure (certificate chains).

Resources