I have an applet for The digital signature.Also i have certificate on PKCS ♯12 which imported to browser.
How can i get this certificate from browser using applet?
You want something like this:
KeyStore ks = KeyStore.getInstance("Windows-MY");
ks.load(null, null);
Certificate cert = ks.getCertificate(alias);
For more info, check the docs.
Related
I'm trying to get client certificate verification working with ColdFusion10 http requests. Currently, all I'm getting back is a 403.7. I believe ColdFusion isn't picking up my client certificate. Below is the steps I've currently taken to install and get it set up.
What I've done:
Created a self-signed SSL certificate and installed it to my default website on IIS 7.5.
Installed the SSL cert into CF store.
Tested HTTPS request, everything works fine.
Followed this guide for CA and Client Certs. https://ondrej.wordpress.com/2010/01/24/iis-7-and-client-certificates/
Installed the CA cert to server and client (through MMC). Installed client cert (.pfx) on client.
Tested in local browser, everything is working as it should up to this point.
Created another client cert for CF10 (.cer, .pvk, .pfx).
Added the CA cert into CF store.
Tested, HTTPS rejected with 403.7.
Added CA cert, client .pfx and .cer through MMC under CF10.
Tested, rejected again with 403.7 still.
I've seen that there has been issues with CFHTTP and client certs before, but I haven't found an solution yet.
If anyone can help me with this, it would be great.
EDIT:
After doing what Miguel-F suggested, I skimmed through the log files and found that my CA was imported inside the ColdFusion trust store, but my client certificate wasn't there. I assume this is the reason for the 403.7.
However, I can't add my client certificate(.pfx) to the trust store using certman or keytool through cmd. I created the .pfx by merging my .cer and .pvk together, so I have both of those also.
How can I add my .pfx to the trust store so that Coldfusion picks it up and validates my https?
EDIT #2:
After following this to add my .pfx to the keystore, I can now see my client cert along with my CA being added as 'trusted cert' during the https request.
However, I'm still getting the 403.7 - Forbidden error.
Edit #3:
The handshake in ssl debug info after adding my .pfx (see edit #2) is:
'Is initial handshake: true'
'catalina-exec-3, WRITE: TLSv1 Handshake, length = 181' (Several of these in 1 request)
Edit #4 (More Debug Info):
The last section above where it returns 403 in the debug info looks like HTML content for the error page returned by the server. Just above that however is this:
catalina-exec-3, READ: TLSv1 Application Data, length = 5808
Padded plaintext after DECRYPTION: len = 5808
0000: 48 54 54 50 2F 31 2E 31 20 34 30 33 20 46 6F 72 HTTP/1.1 403 For (Example of the HTML error content)
Edit #5:
I can see my client cert being added as a trusted cert during the start of the request... It's just not using it.
adding as trusted cert:
Subject: CN=George CF10
Issuer: CN=MyPersonalCA
Algorithm: RSA; Serial number: 0x-431b7d9911f9856cb0adf94d50bb1479
Valid from Fri Apr 01 00:00:00 BST 2016 until Wed Apr 01 00:00:00 BST 2020
Edit #6:
After adding setClientCert(path to my .pfx) and setClientCertPassword(client cert password) to my https request, I'm seeing this error:
Error while trying to get the SSL client certificate:
java.security.UnrecoverableKeyException: Could not decrypt key: Could not decode key from BER. (Invalid encoding: expected tag not there.).
Check that the certificate path and password are correct and the file is in PKCS#12 format.
Too long for comment
Are you sure that you added the certificate to the correct JVM keystore? If you have upgraded Java on your ColdFusion server then it may not be in the default location. The ColdFusion administrator system information page will tell you the path in use under the "Java Home" label.
In order to turn on debugging information, add these lines to your ColdFusion server's jvm.config file located under this directory C:\ColdFusion10\cfusion\bin (by default) and restart the ColdFusion service:
-Djavax.net.ssl=debug
-Djavax.net.debug=all
This should add some more information to the coldfusion-out.log log file on your server. Post that information back here into your question for further analysis.
Adding the certificate to the Windows server using MMC is not needed and does not help your cfhttp calls from ColdFusion. It uses the Java keystore.
Response for EDIT 1 and 2
Follow the steps from this other answer on how to convert a .pfx file to the keystore.
Response for EDIT 3, 4 and 5
If you still have the ssl debug switch turned on you should see the handshake info in the log file. What does it show now that you have the certificate installed?
Have you tried using the clientCert and clientCertPassword attributes of the cfhttp tag? Note that it will require the full path to a PKCS12 format file that contains the client certificate for the request. See the docs here.
Response for EDIT 6
Take a look at this page - CFHTTP and client certificates regarding the error message you are getting: Could not decode key from BER. Excerpt from that page:
The client certificate appeared to be a normal client certificate with private key in PKCS#12 format, but from a different certificate chain then the server format. So I first had the client double-check that the chain was correctly installed on the server. Unfortunately it wasn’t that easy. I will spare you the details of what I tried, but in the end it turned out to be that the certificate was incorrectly encoded. These are the actual conversion steps I took to convert the certificate to a working state:
import the certificate in the Windows Certificate store through the MMC;
export the certificate with private key, whole chain and without strong encryption in PFX formet;
convert the PFX encoded certificate to PEM using OpenSSL:openssl pkcs12 -in raw.pfx -out intermediate.pem -nodes
re-order the certificates inside the PEM file to the following order: > - Identity certificate
Intermediate certificate
Root certificate
Private Key
convert the PEM encoded certificate to PKCS#12 using OpenSSL:openssl pkcs12 -export -out final.pkcs -in final.pem
It is probably possible to skip / merge a few of these steps (you probably just need to convert to PEM, reorder and convert back), but I really didn’t have time to explore that, I just know that this worked for me.
Solved by following this link.
I used the new .pkcs format file inside setClientCert of the HTTP request and it is now working.
import the certificate in the Windows Certificate store through the MMC;
export the certificate with private key, whole chain and without strong encryption in PFX formet;
convert the PFX encoded certificate to PEM using OpenSSL:
openssl pkcs12 -in raw.pfx -out intermediate.pem -nodes
re-order the certificates inside the PEM file to the following order:
Identity certificate
Intermediate certificate
Root certificate
Private Key
convert the PEM encoded certificate to PKCS#12 using OpenSSL: openssl pkcs12 -export -out final.pkcs -in final.pem
It is probably possible to skip / merge a few of these steps (you probably just need to convert to PEM, reorder and convert back), but I really didn’t have time to explore that, I just know that this worked for me.
I am using the Argon 3 web browser with Vuforia's image tracking. I've taken the license key of my Vuforia application and encrypted it with the GPG Keychain. I've included relevant snippets of my index.html and app.js files here.
Whenever I load up my application, I get the error:
Vuforia: could not decrypt vuforia license JSON
Running it in the debugger shows:
Unexpected token VSyntaxError: Unexpected token V
at Object.parse(native)
...
index.html
<script id="license" type="text/plain">-----BEGIN PGP MESSAGE-----
Comment: GPGTools - https://gpgtools.org
hQIMA3/IreB2WlL1AQ//WZ4evbtnP39ycrb5Z8fa1U0ugbjGOfVA1h0nhgye3IhF
UMRcDF4nJ/+LKYzcePI7orjwjfedTKfX3oVrqb8focLoQvBKwG6bgRhAIr9oTwtO
uXXOVeZFo9iCnEicwGvGtdgUVv/EQHl/VIstLg3+aEtV3Xpjnlx7r2VbUp9L7iEp
mhaTLVpAcgWyqyPYN3QoEbBEtjdRKnHAogb268ZKEWSVjtcDo9NQCI/Lfb+3ghZS
mBVxr3d4Jtb8mcpOYeUfMilD5BuzelhciJb0PPFVdj/JmcVpDsFNNX/FvFNIlm0c
qH64s+ByHGiCGcQeAJx/ZAF9cTjBYDk3HZLlPWHOD7rA1roHLujN/yf3UpLkBFFn
jEj/MMO3KSWJUAXVs+vNpThgqwgIDPeuV9nKH5QeQORpKp3zOVVsXGGYxbVY7sDl
3sbXTYghhE5XM21t4/A/iFwJxB1ndqbhfiA/kdQwsKAb17OdBVzldQ1Wh/JouTFB
m1ETnviMDKZYw7a9yiavvCjjxJHedmQNPWJVJBiOeHvGZLOpdV47TZwiXLs6dsqJ
NxB0352AOw4v66nk6RMUwclAhiz4ll0xQIPTWQpjIjOhf7COK1jFXUs+PDS21MVq
1nwjDDAjKsfj4dxPbzJUGuQwaNqI/Jg7BqhVxo/uZxtvw9c+ERcHdMY9EnK6aMLS
wSABq1kaId5VF5ccHO999AKWrB9IIhpahlFRi3asU62Cz4DZ6XqbiTDTFpmX1ZG0
6JynBv4+H/SH45TPgsBMs6IMgWPrGxTmpipte6W2X98lf5ogzWnSOGv5J7BDYtLz
0GruiAjcIOpneDx4x+i5gh/0GjBIM1ZlaHhW3Gl+zxRj8X2vhoGXFg/qB5YKk05T
womuhvDCGbO0fO1oSlZP+1kjqfsyN8k67LyWwjVvuoGfwrv3WS4dwVTB6YlCKM6l
LH1GcHmkdBVTFHQsltzbeIllcJ2QLSqWRIfPeB0eIAMh9G8P8397I9fWznBGGIz6
lXlH3AF50+cwruWTpv0Jnjyd+n3wGc14UFgaEgjWFCK04OOaZVUuRuJG900VT2qV
Nh8y9KsdTMGkVfU25BA8k04Vi6IKDnl2vbQWnYCs5wsFfj/e2/5B4Ixx7ekjgi5/
vylNv8t12ollHapJ5zSx7KzyV77N3Gam6PrORovx6evIEe+fXnPJoZkMrNRbKv/Z
uH5DMZQU3CW+Dy4hS4VEmRSM5hFa5SM7GrDAAtxsBoY2oX0AJYKs1RyhzokQCN9O
bV1qkcfW+6kKLq3HbNsMJ45ya2mcXZNaXa+JDeRE22U0csrJSsU4M5us9wZc6XiM
DuQ=
=qaTl
-----END PGP MESSAGE-----
</script>
app.js
// Tell Argon that we need Vuforia for image tracking
Argon.immersiveContext.setRequiredCapabilities('Vuforia');
var encryptedData = document.getElementById("license").text;
// initialize Vuforia with our license key
Argon.Vuforia.initialize({
encryptedLicenseData: encryptedData,
startCamera: true,
}).then(function(api)
{
// load, activate, and use our dataSet
api.loadDataSetFromURL('./auburn_map.xml').then(function (dataSet)
{
dataSet.activate();
setupStreetCar(dataSet.trackables.streetcar);
}).then(api.startObjectTracker)
.then(api.hintMaxSimultaneousImageTargets.bind(api, 2));
});
I am unsure of what to do from here. Any help would be greatly appreciated.
Edit:
I encrypted the JSON file using the GPG keychain. I created a new keypair with the email "secure#argonjs.io", went to my JSON file, highlighted the text, selected that I wanted to encrypt and did NOT sign or encrypt with password.
How did you encrypt this JSON file? You need to encrypt with the secure#argonjs.io public key, and do not sign it or encrypt with a password.
I'm new to security so some of the terms might be used incorrectly:
When I create a socket connection using SSL_connect, the server should send back the entire certificate chain so that the authenticity of the server can be verified.
For this to happen, the server needs to be configured accordingly.
If the server doesn't send back the entire certificate chain and the intermediate certificate isn't in the client certificate store, the authenticity can't be verified. This results in the behavior experienced here in which FireFox regards a website as unsafe.
I've also read that some browsers are able to attain the intermediate certificate automatically. However, OpenSSL doesn't behavior like this, at least by default.
I've also been told that some (maybe all) intermediate certificates have been installed in Windows certificate stores since some Windows update was rolled out a few years ago.
I would like to view the certificates returned by the server to verify that I'm getting back the entire certificate chain. Here's what I've tried:
I'm using SSLv3_method.
SSL_CTX_set_verify is set using SSL_VERIFY_NONE.
After SSL_connect I use SSL_get_peer_cert_chain to get access to the certificate chain.
Consider:
STACK_OF(X509)* certificateChain = SSL_get_peer_cert_chain(ssl);
while (char* stackCertificate = sk_pop(certificateChain))
{
X509* certificate = (X509*)stackCertificate;
}
Is this the correct way to get the certificate chain? Is my understanding of the situation correct? Is there perhaps a better way to do this?
Thank you for your time and contribution.
The following code snippet is based off code in s_client:
SSL* ssl = ...;
STACK_OF(X509)* certCollection = SSL_get_peer_cert_chain(ssl);
for (size_t i = 0; i < sk_X509_num(certCollection); i++)
{
X509* cert = sk_X509_value(certCollection, i);
...
}
As far as I understand, an SSL session must have been created otherwise SSL_get_peer_cert_chain will return null. Additionally I haven't found any evidence to contradict the list I noted in my question.
Perhaps an easier alternative would be to use the command line tool (downloaded from here):
openssl s_client -connect {server}:{port} -ssl3
I've got a Node.js server that runs on sub.domain.com, using SSL. It's been working perfectly for months on desktop browsers, but I just noticed that it doesn't work on mobile browsers.
I've done a bit of research and there's a lot of people suggesting that there is something wrong with my certificate chain. I've changed my code to look like there's but still no luck.
Here's my code:
var httpsOptions = {
ca: [fs.readFileSync("certrequest.csr")],
key: fs.readFileSync("privatekey.pem"),
cert: fs.readFileSync("certificate.pem")
};
var app = http.createServer(httpsOptions, function(req, res) {
log.cnsl.write("HTTP Request received from " + req.connection.remoteAddress);
//Do stuff
});
I'm running this command to view some debug information (my server runs on port 5673):
openssl s_client -connect sub.domain.com:5673 -showcerts | grep "^ "
Below is the important part of that output
depth=0 O = *.domain.com, OU = Domain Control Validated, CN = *.domain.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 O = *.domain.com, OU = Domain Control Validated, CN = *.domain.com
verify error:num=27:certificate not trusted
verify return:1
depth=0 O = *.domain.com, OU = Domain Control Validated, CN = *domain.com
verify error:num=21:unable to verify the first certificate
verify return:1
It sounds rather weird that you've put your certificate request file "certrequest.csr" as the CA.
The CA field should contain the certificate chain from your personal certificate to th root certificate. In my configuration, it contains 2 entries. One as the root certificate itself and the second one as the intermediate one because my issuer offers multiple levels of certifications.
By the way, your certification company most certainly provides you with such informations in their FAQ for example.
As an example, here is an extract of my configuration :
var httpsOptions = {
key:fs.readFileSync('/etc/ssl/private/ssl-main.key'),
cert:fs.readFileSync('/etc/ssl/private/ssl-main.crt'),
ca:[fs.readFileSync('/etc/ssl/private/ca.pem'),
fs.readFileSync('/etc/ssl/private/sub.class2.server.ca.pem')]
};
Anyway, this does not explain why It works for non mobile browsers. My only guess is that they my embed themselves a part of the chain while the mobiles wont't for disk space reasons.
Hope this helps.
This is an extension question to:
how-do-i-create-a-self-signed-certificate-for-code-signing-on-windows
To take this further, if I have created a CA cert, and have create a set of SPC certs, how do I go about creating revocation lists and distributing them? (note: I have no knowledge about how CRLs work, how they are distributed etc) If I were to GUESS how it all worked, I would hope that the CA cert defined some HTTP address where CRLs could be downloaded, and windows would contact that address the first time a cert chain was queried, and every time the current CRL expires... Then all I would have to do is create a signed web address that distributes certificate serial numbers...?
EDIT: SELF ANSWERED
For anyone else who is interested, Bouncy Castle is a Java+C# library providing a massive set of PKI Crypto APIs, including certificate generation.
Their sample code (in their downloads) demonstrates how to generate a chained set of CA, Intermediate, and 'Personal' certificates.
What it doesnt show, is how to correctly assign an HTTP based CRL - you can do so with this code:
GeneralName gn = new GeneralName(new DerIA5String("http://localhost/revocationlist.crl"), 6);
GeneralNames gns = new GeneralNames(gn);
DistributionPointName dpn = new DistributionPointName(gns);
DistributionPoint distp = new DistributionPoint(dpn, null, null);
DerSequence seq = new DerSequence(distp);
v3CertGen.AddExtension(X509Extensions.CrlDistributionPoints, false, seq);
As of crypto-147 the supplied code has changed to
GeneralName gn = new GeneralName(GeneralName.uniformResourceIdentifier, new DERIA5String(crlUrl));
GeneralNames gns = new GeneralNames(gn);
DistributionPointName dpn = new DistributionPointName(gns);
DistributionPoint distp = new DistributionPoint(dpn, null, null);
DERSequence seq = new DERSequence(distp);
certGen.addExtension(Extension.cRLDistributionPoints, false, seq);
Suppose you have a CA certificate and some set of certificates, signed by that CA certificate. Then you can create a CRL, which would (potentially) contain IDs of revoked certificates, which were previously signed using CA certificate. Indeed you add the URL of the CRL to the CA certificate itself via the corresponding certificate extension (CRLDistributionPoint).
As you have not specified, what tools or libraries you use to generate the certificates, I can't say how the extension can be added.
PS: I'd recommend that you learn about technology before trying to use it. Especially when it comes to implementing security. Otherwise you will end up in situation, worse than the one of Comodo, whose sub-CAs have issued fake certs for google, yahoo and more just recently.