What is the best way validating a signature/certificate? - c

I am working on an application, where I have to verify that 2 files are signed with the same certificate(with our certificate). If not, then abort the program.
I found in this question, what I should do:
Validate the certificate chain completely to ensure integrity and authenticity of the certificate
Check issuer name
Check subject name
Check key usage field.
So for step 1, I use WinVerifyTrust, then I read the propertys, and compare them with each other.
So far so good, but what if someone creates a certificate, and signs these two files with them? Then it will still work. I know, that if this certificate is not added as Trusted Publisher, then WinVerifyTrust will fail. But let's say, it is added as a Trusted Publisher. Then it works. Obviously I can't write the values like "my company name" in the code, and check if a property has this value.
So how do I check if it is really my certificate? If it is really a certificate which is "Trusted", not only made trusted by me or someone else?
Thanks in advance!

If you have access to the certificate issuer (just the public key) and you trust that public key (you have acquired it by other means ---it doesn't come with the certificate you are validating, you have it already stored locally or the like--- this is the only reason to have a certificate chain) you have only to verify that the signature is valid to ensure that tha user certificate is valid. The certificate chains are only to ensure that you have one path to ensure certificate validity up to a root certificate you trust in (normally the root certificates that come with software distributions)
subject checking (or other certificate fields) is needed only in case you have different profiles or types of accounts depending on the information stored in the certificate. What use you do on subject format or fields acompanying the certificate is up to the application. Normally, people embedd information about the user account in the certificate so you can use certificates to distribute account info.
Remember that a certificate is only a public key (and some other information for whatever purpose you want it to be used to) signed by a trusted authority (this can be an intermediate certificate or a root certificate) so, once you verify the signature, you get inmediate trust on the contents. The certificate contents cannot be changed without access to the private key of the certificate issuer (to be able to sign it again) so you can trust that data in case the signature verifies ok.
How do you test if a certificate is really yours? Of course it has to be signed by a certificate issuer (this can be you or an issuer you have trust in) and verify that the issuer is that and no other certificate. In case of a corporate application you have to check that one of the signers is a certificate authority (normally for each application or application module, one or different certificate issuers are generated, each one signing user certificates that belong to that module) if you find that issuer in the certificate chain, then you can trust the certificate for the intended use.

Related

How to generate a certificate signing request (CSR) file and a KeyPairs in Azure ADB2C?

I have a usecase to create a KeyPair within Azure ADB2C, and with these Keypair need to generate a “CSR Certificate file” and share to back team.
Where I have gone through couple of references to achieve this scenario but no solution yet.
Is there any proper method to create a “KeyPair” using ADB2C policy-keys option, and using those keys how to generate a CSR certificate file? if there any approach exists?. Also, is there any way that we can generate a CSR file without azure keyvalut within ADB2C portal?
##your valuable suggestions might helps a lot.
Thank you!!
A CSR is just a certificate request. When you create a certificate request, the public and private key pair is generated directly in Key Vault, and then the certificate request with the public key can be downloaded, signed, and merged back into Key Vault so that the certificate is trusted as long as your signing certificate chain terminates in a trusted root for the application verifying the certificate.
If you're looking to automate this process, see our Azure SDKs for Key Vault certificates.

ADFS + OpenID Connect email claim and external ADFS

I'm having difficulties setting up ADFS with OpenID Connect on Windows Server 2016.
I've setup AD for testing and I can successfully authenticate, however the email claim is not in the id token.
Additionally I've setup an external ADFS in the Claims Provider trust. It is displayed as an option, however upon logging in I get the error:
MSIS9642: The request cannot be completed because an id token is required but the server was unable to construct an id token for the current user.
Anybody have suggestions on how to fix this?
The root cause of MSIS9642 is that the new OpenID Connect Application Group features in ADFS 2016 need to issue an access token to your application. This token must include the users identity. In order to issue the token the subsystem must understand which claim in the inbound claims is used to uniquely identify the user.
A new property called AnchorClaimType has been added to the Claim Provider Trust model.
When ADFS is first installed it registers a built in Claim Provider Trust for AD AUTHORITY and sets the value for AnchorClaimType to
foo://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname
You can see this by using the powershell command get-adfsclaimsprovidertrust.
This is why OpenID works for when authenticating against Active Directory.
When you create a new Claim Provider Trust the system does not set an AnchorClaimType. The OpenID system can't issue a token because it does not know which inbound claim constitutes the unique user identity. This is why OpenID does not work when authenticating against an external Claim Provider trust.
In order to resolve this problem you need to take a few actions:
a) Verify that you are running Windows Server 2016 RTM Unfortunately the powershell attribute to set AnchorClaimType does not exist in the CTP, and the property cannot be set using the UI.
b) Choose a claim from the inbound token that represents the users identity and identify the claim type. In our case we were federating with an Azure Active Directory and chose name, and the type is foo://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
c) Set the AnchorTypeClaim for the Claim Provider Trust to the type selected by using powershell
set-adfsclaimsprovidertrust -targetidentifier identifier -AnchorClaimType http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name
(get identifier from powershell get-adfsclaimsprovidertrust)
d) Create at least one inbound rule that passes through the value for the primary input claim, in our case Name
Hope this helps
To solve the problem with the missing AnchorClaimType parameter for additional added Claim Provider Trusts (CPT) a workaround for Windows Server 2016 TP5 (until end of support) can be used.
Workaround:
If CPT is already existing, delete the CPT.
Use the powershell command Add-AdfsClaimsProviderTrust
Either parameter wise (see Technet Description)
Or using a Metadata URL + the Parameter -AnchorClaimType "yourAnchorClaimValue".
Create at least one inbound rule that passes through the value for the primary input claim
In my case the following PS command solved the problem:
[String]$ClaimProviderTrustName = "YourCPTName"
[String]$MetaDataURL = "https://..."
[String]$AnchorClaimType = "YourAnchorClaimValue"
Add-AdfsClaimsProviderTrust -Name $ClaimProviderTrustName -MetadataUrl $MetaDataURL -AnchorClaimType $AnchorClaimType
I work at Microsoft. My customer had this same error. This is how we fixed it. We used Claims x-ray. We had them do a login with an identity from Active Directory and then do a login with an identity that uses an external claims provider trust.
When we compared the Claims X-Ray output, the value for anchorclaimtype didn't look right on the claims provider trust test login. We made a change in the claims provider to issue http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress as the anchor claim type and it resolved the problem.
v-michall#microsoft.com

Msi & exe singing Microsoft Authenticode requirments

I am trying to sign my small application, following this tutorial:
In the tutorial they did not ask me to purchase Microsoft Authenticode Certificates
I need to Removes "Unknown Publisher" security warnings; after I signmy msi and exe files I still have "Unknown Publisher"
Can I sign my msi or exe without purchasing Microsoft Authenticode Certificates?
I know that I can sign Java, Authenticode, and AIR apps free: https://www.globalsign.com/en/code-signing/code-signing-tool/
No you can't remove "Unknown Publisher" security warnings without purchasing a code signing certificate.
The tutorial link describes how to create a test certificate. Quoting the first paragraph "If you use a test (self-created) certificate, the installation dialogs will display an "Unknown publisher" message."
When you purchase a code signing certificate, the certifying authority takes certain steps to verify your identity. If those steps are passed, the certifying authority issues you a certificate signed by their private key. The private key is kept secret. When you install code signed software, the operating system extracts the code signature from the software and validates it against the public key provided by the certifying authority. This is a simplification, the actual check involves a chain of certificates. But the key point is: if you use a self signed test certificate, the operating system has no knowledge of the public key of the self signed test certificate so cannot validate against it.

How to securely store a password in a database while still being recoverable

For an application that I am working on I want to store passwords that a user enters in a way that provides some security in the event that my database is compromised but still allows an external daemon to have access to the plaintext version of the password. (It will be used for IMAP or POP logins).
What is the best way to store a password in the database so it is recoverable without the user's original password. (Not encrypted with the user's password)
I was thinking maybe public key encryption where the front end would use the public key to encrypt the password for store in the database and then the accessing daemon would decrypt the password with the private key.
EDIT:
I need the plaintext passwords so that they can be used to log on to other websevices which may not support something like OAuth
You should encrypt them, preferably with asymmetric encryption. Ideally the application (web app) encrypts them (w public key), and the daemon decrypts them (w private key), and the application and daemon and db live on different machines in different network zones.
Ideally the private key lives in a hardware security module attached to the daemon server. YubiHSM is ~ $500.
Please note that this only applies to passwords that you need to send to another party. If the password is for authenticating users with your system, then they should be hashed (and salted, and peppered).

Securly Storing OpenID identifiers and OAuth tokens

I am creating a web app that will use OpenID logins and OAuth tokens with Youtube. I am currently storing the OpenID identity and OAuth token/token secret in plain text in the database.
Is it inappropriate to store these values as plain text? I could use a one-way encryption for the OpenID identifier but I don't know if that is necessary. For the OAuth tokens, I would need to use a two-way encryption as my app relies on getting the session token for some uses.
Is it necessary to encrypt the OpenID identity? Could someone use it to gain access to a user's account?
First, there is a registered application that has consumer_key and consumer_secret.
When users authenticate and "allow" your registered application, you get back:
an access_token that is considered the user's "password" and would allow JUST YOUR application to act on the user's behalf.
So, getting just the user's access_token from your database won't help much if they don't also have the consumer_key and consumer_secret for complete access.
The service provider compares all 4 parameters on request. It would be smart to encrypt these 4 parameters before storage and decrypt them before response.
This is just when you need to update or make changes to the user's resource owner on behalf of a user. To keep a user logged-in on your site, use sessions.
The OAuth Token and Secret should both obviously be kept safe in your database, but you can't store them using 1 way encryption the same way you would for a password. The reason being is that you need the token and secret to be able to sign the request.
This would also be the case if you are running an OAuth server, you still need the original token/secret to verify the request.
If you want to you could still encrypt them using a 2 way encryption algorithm such as AES to offer security in case your database or database backups get compromised.
There's two schools of thought here.
The first argument is that: you should treat OAuth tokens like passwords. If anyone were to access your database, obtain all the OpenID/OAuth pairs and run an man-in-the-middle attack, they could impersonate any user on your site.
The second argument is this: by the time someone has access to your database and sufficient access to your network to run an man-in-the-middle attack, you're hosed anyway.
I'd personally err on the side of caution and just encrypt them; it's a standard practice for passwords, so you might as well give yourself just that little extra peace of mind.
Meanwhile, Google has this advice:
"Tokens should be treated as securely as any other sensitive information stored on the server."
source: http://code.google.com/apis/accounts/docs/OAuth.html
And some random guy on the web has specific implementation advice:
If they’re on a regular disk file, protect them using filesystem
permissions, make sure that they’re
encrypted, and hide the password well
If they’re in a database, encrypt the fields, store the key
well, and protect access to the
database itself carefully. *
If they’re in LDAP, do the same.
archived post (original post URL, now a dead link)
OpenID URL shouldn't be encrypted because this is your "open id" literally, everyone should know the value. Besides, the URL needs to be an index in the database and it's always problematic to encrypt the index in the database.
OAuth token/secret should be secret and encryption may improve security if you have to store the token long term. In our OAuth consumer application, token/secret is only stored in session for a short while and we choose not to encrypt them. I think that's secure enough. If someone can peek into our session storage, they probably have our encryption key also.
Yes, these should be symmetrically encrypted (say, AES-256 in CBC mode) at rest in a database. A simple way to encrypt these tokens is using SecureDB's Encryption as a Service RESTful APIs.
Disclosure: I work at SecureDB.

Resources