WSO2 IS: Change HTTPS certificate - https

I am a total newbie in WSO2 configuration and a relative newbie in how HTTPS certificates work, so please bear with me.
I am trying to change the certificate for HTTPS connections in WSO2. Without any configuration WSO2 returns a certificate with the DN CN = localhost,O = WSO2,L = Mountain View,ST = CA,C = US. I am trying to change this with my own certificate, following the instructions from this blog article.
I have imported my certificate in the keystore and changed the config as described in the article. One notable difference is that I couldn't find ${carbon.home}/repository/conf/mgt-transports.xml.
After doing this, connecting to the IS server management service results in the "localhost" certificate being returned, instead of the one imported.
The KeyStore and RegistryKeyStore entries in repository/conf/carbon.xml
<KeyStore>
<!-- Keystore file location-->
<Location>${carbon.home}/repository/resources/security/wso2carbon.jks</Location>
<!-- Keystore type (JKS/PKCS12 etc.)-->
<Type>JKS</Type>
<!-- Keystore password-->
<Password>wso2carbon</Password>
<!-- Private Key alias-->
<KeyAlias>testcert</KeyAlias>
<!-- Private Key password-->
<KeyPassword>wso2carbon</KeyPassword>
</KeyStore>
<!--
Encrypt Decrypt Store will be used for encrypting and decrypting
-->
<RegistryKeyStore>
<!-- Keystore file location-->
<Location>${carbon.home}/repository/resources/security/wso2carbon.jks</Location>
<!-- Keystore type (JKS/PKCS12 etc.)-->
<Type>JKS</Type>
<!-- Keystore password-->
<Password>wso2carbon</Password>
<!-- Private Key alias-->
<KeyAlias>testcert</KeyAlias>
<!-- Private Key password-->
<KeyPassword>wso2carbon</KeyPassword>
</RegistryKeyStore>

Step 1: Create a new keystore with private and public key (key-pair).
Inside /repository/resources/security/ directory. The default keystore (wso2carbon.jks) and truststore (client-truststore.jks) will be stored here.
• Create a keystore containing a key-pair using java key tool (contained in the standard jdk) and save it as a jks file. The keystore contains THIS server’s key-pair (public & private keys).
• The Keystore/Key-Pair should have the following properties/attributes :
KeystoreType = JKS,
KeyPairAlgorithm = RSA,
Size = 2048 bits
SignatureAlgorithm = SHA-256 WITH RSA
Password (Must be exactly the same as the keystore password)
Name(Subject): The CN(Common Name) of the key-pair should be the server’s hostname upon which the IS will be deployed (if you intend to use it as the key manager for api manager)
Extensions:
Key usage : Digital Signature , Key Encipherment , Data Encipherment , on Repudian
Subject Alternate name : IP address = IP address of this server
Step 2: Import the certificate chain from the keystore created in Step 1 into a truststore.
Create new trust store with same attributes
• Export the certificate from the Keystore (step 1) into the truststore
Step 3: Change the configuration files as follows, reflecting the new keystore and truststore that have just been created.
Change the appropriate values in the following files (in /repository/conf/):
File Line number/s
identity.xml 180
carbon.xml 310
326
343
axis2/axis2_pt.xml 272
280
396
404
axis2/axis2.xml 272
280
396
404
axis2/axis2_nhttp.xml 278
286
405
413
security/secret-conf.properties 21
30
sec.policy 1
More or less , just search the files for "jks"
Delete the old keystores
Step4: Restart

Related

elastic search issue with Open Distro

we have defined the following in .ini file:
Assigned Values:
opendistro_security.ssl.http.enabled= True
Kesystore type = PKCS12
keystore_filepath = /relativepath.pfx
truststore_type = PKCS12
truststore-filepath =/relativepath.pfx
opendistro_security.ssl.transport.keystore_password=""
opendistro_security.ssl.transport.truststore_password=""
We are getting below error message when we execute .Net application:
Error:
Caused by: org.elasticsearch.ElasticsearchSecurityException: Error while initializing transport SSL layer: java.io.IOException: keystore password was incorrect
Caused by: java.security.UnrecoverableKeyException: failed to decrypt safe contents entry: javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
Resolutions we tried:
Changed different passwords of Pfx as well as defined in setting_override.ini (eg. “changeit”). Also added Pfx file to respective directory.
Checked PFX file by both import/ export by creating new password and also added that in MMC and checked.
Added default password for Truststore type and Keystore Type as per the this URL
Placed Pfx file inside config folder of Elastic Search
But still we are facing issue.
In this URL they have mentioned the following settings such as:
ELASTIC_PASSWORD=password
- xpack.security.enabled=true
- xpack.security.http.ssl.enabled=true
- xpack.security.http.ssl.keystore.path=/usr/share/elasticsearch/config/elastic-certificates.p12
- xpack.security.http.ssl.truststore.path=/usr/share/elasticsearch/config/elastic-certificates.p12
- xpack.security.http.ssl.keystore.password=password
- xpack.security.http.ssl.truststore.password=password
- xpack.security.transport.ssl.enabled=true
- xpack.security.transport.ssl.verification_mode=certificate
- xpack.security.transport.ssl.keystore.path=/usr/share/elasticsearch/config/elastic-certificates.p12
- xpack.security.transport.ssl.truststore.path=/usr/share/elasticsearch/config/elastic-certificates.p12
- xpack.security.transport.ssl.keystore.password=password
- xpack.security.transport.ssl.truststore.password=password
Queries:
Do we need to mention all this settings for our application?
Is the above setting applicable for XPack (or) it will get applicable for Open Distro also?
Is elastic search will have separate password? If so where can we check password related to Elastic Search?
Do we need to assign same password of Elastic search to Truststore type and Key store type?

Azure Cloud Service definition xml datatype error

I can't specify "Let's Encrypt . . " in Azure Cloud definition for certificate name. I need to specify intermediate certificate name, can't change the name.
Wrong:
<Certificate name="Let's Encrypt Authority X3"
Right:
<Certificate name="Lets Encrypt Authority X3"
Because ServiceDefinition:NamedElementNameString doesn’t allow apostrophe(').
Also I have tried:
<Certificate name="Let&apos;s Encrypt Authority X3"
Adding SSL cert as per this: https://learn.microsoft.com/en-us/azure/cloud-services/cloud-services-configure-ssl-certificate

APNS: CSR generated from Windows is invalid

I'm trying to enable push notifications in my app, the problem is that I can't generate the certificate because whenever I upload my CSR (generated from Windows) I get the following error:
Invalid CSR Select a valid Certificate Signing Request.
The CSR was generated using the following specs:
Key Size 2048 bit
RSA Algorithm
I did the same process last year and I was able to generate the certificate but now all I get is the error above.. did Apple change anything about the CSR or am I missing something?
found it........
The CSR first and last line were:
-----BEGIN NEW CERTIFICATE REQUEST-----
.
.
.
-----END NEW CERTIFICATE REQUEST-----
I had to remove the NEW word and it worked, I was able to generate the .cer file

trusted certificate entries are not password-protected Spring SAML

I have generated testIdp.cer file by copying 509 entry of the IDP I am planning to connect. Then I created JKS file by executing the following command
keytool -importcert -alias adfssigning -keystore C:\Users\user\Desktop\samlKeystore.jks -file C:\Users\user\Desktop\testIdp.cer
When executed it has asked to enter a password for which I have given a password. For the question "Trust this certificate? [no]:", I have given "y" as input. Message came out as "Certificate was added to keystore".
Then I have configured the following details in securityContext.xml
<bean id="keyManager" class="org.springframework.security.saml.key.JKSKeyManager">
<constructor-arg value="classpath:security/samlKeystore.jks"/>
<constructor-arg type="java.lang.String" value="mypassword"/>
<constructor-arg>
<map>
<entry key="adfssigning" value="mypassword"/>
</map>
</constructor-arg>
<constructor-arg type="java.lang.String" value="adfssigning"/>
</bean>
<bean class="org.springframework.security.saml.metadata.ExtendedMetadata">
<property name="alias" value="adfssigning" />
<property name="signingKey" value="adfssigning"/>
</bean>
But when I run the application, I get the following two exceptions when the server is starting and when I load the homepage of the application. Can anyone let me know if I am missing anything else.
This exception is occuring when I start the server
Caused by: org.opensaml.saml2.metadata.provider.FilterException: Signature trust establishment failed for metadata entry
at org.opensaml.saml2.metadata.provider.SignatureValidationFilter.verifySignature(SignatureValidationFilter.java:327)
at org.opensaml.saml2.metadata.provider.SignatureValidationFilter.processEntityGroup(SignatureValidationFilter.java:240)
at org.opensaml.saml2.metadata.provider.SignatureValidationFilter.doFilter(SignatureValidationFilter.java:158)
at org.opensaml.saml2.metadata.provider.AbstractMetadataProvider.filterMetadata(AbstractMetadataProvider.java:493)
at org.opensaml.saml2.metadata.provider.AbstractReloadingMetadataProvider.processNonExpiredMetadata(AbstractReloadingMetadataProvider.java:395)
This exception is occuring when I run the homepage of my application
java.lang.UnsupportedOperationException: trusted certificate entries are not password-protected
at java.security.KeyStoreSpi.engineGetEntry(Unknown Source)
at java.security.KeyStore.getEntry(Unknown Source)
at org.opensaml.xml.security.credential.KeyStoreCredentialResolver.resolveFromSource(KeyStoreCredentialResolver.java:132)
Your .cer certificate contains only a public key, you mustn't define <entry key="adfssigning" value="mypassword"/> for public keys; it can only be used for private ones. Simply take out the adfssigning entry and make sure to include a private key instead - just like in the Spring SAML sample application.
The SAML keystore can contain two basic types of keys - public and private ones (plus their certificates). Each key has an alias which is used to refer to it. The keystore itself can be protected by a password (provided in the second constructor parameter), plus each private key can be also protected by an additional password (these are defined in third parameter of the constructor in a map of alias->password). The public keys which you import to the keystore (just like you did with the command above) mustn't be defined in this map. They will be automatically available after being imported without additional declarations. For Spring SAML to work, the keystore must contain at least one private key (the sample application contains private key with alias apollo) and its alias needs to be provided in the third parameter of the constructor.
Your example above fails, because you have imported a public key, but included it in the map which can only be used for private keys.
Vladimir answered correctly the question why the error occurs.
In my answer I want to show how you can import a certificate to the keystore to solve that problem:
You have to import the certificate and private key which could not be done directly by keytool.
The detailed described solution is found here: https://stackoverflow.com/a/8224863/1909531
Here's an excerpt:
openssl pkcs12 -export -in server.crt -inkey server.key \
-out server.p12 -name [some-alias] \
-CAfile ca.crt -caname root
keytool -importkeystore \
-deststorepass [changeit] -destkeypass [changeit] -destkeystore server.keystore \
-srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass some-password \
-alias [some-alias]
After trying everything, deleting and recreating the jks files multiple times, nothing worked. I then happened to scroll this page and found Pankaj's answer and that was it. I was using the wrong alias in the properties file. As correctly mentioned by Pankaj, We should be using the alias of the PrivateKeyEntry and not the trustedCertEntry in the properties file.
Steps are then as follows :
Create a JKS file using the command below. This would also add the PrivateKeyEntry to the JKS file.
keytool -genkeypair -alias some_alias -keypass some_password -keyalg RSA -keysize 2048 -keystore samlKeystore.jks -validity 1825
Import the IDP cert into it. This would add the trustedCertEntry to the file.
keytool -importcert -alias some_other_alias -file file_name -keystore samlKeystore.jks
Modify your properties file to use the alias you gave while creating the JKS file i.e. the alias for PrivateKeyEntry
sso.keystore.privatekey.alias=some_alias
sso.keystore.default.certificate.alias=some_alias
restart your server.
One other mistake I did in the beginning was that I got a metadata.xml file from IDP and had to create a cert file. I forgot to add the "-----BEGIN CERTIFICATE-----" and "-----END CERTIFICATE-----" before and after the cert, which then generated an invalid cert and gave me grief. Teh cert should be in the format below
-----BEGIN CERTIFICATE-----
BLAH-BLAH-BLAH-CERT
-----END CERTIFICATE-----
This error occurs also when you don't have a private key in your Keystore. SAML uses the private key to generate the Service provider meta data used to communicate with the IDP.
Just add one to the Keystore like this:
keytool -genkey -v -keystore some_key_store.jks -alias some_alias -keyalg RSA -keysize 2048 -validity 36500
Fill in the questions and set validity to an appropriate number of days. (In my example it's valid for 100 years)
Remember to add the public certificate from IDP. Then you should be ready to go.
For those looking for answers in java config please comment out the line
passwords.put("mykeyalias", "mystorepass"); .... shown in code snippet below.
#Bean
public KeyManager keyManager() {
DefaultResourceLoader loader = new DefaultResourceLoader();
Resource storeFile = loader.getResource("classpath:saml-keystore.jks");
Map<String, String> passwords = new HashMap<>();
// passwords.put("mykeyalias", "mystorepass");
return new JKSKeyManager(storeFile, "mystorepass", passwords, "mykeyalias");
}
After all the above solutions,if the problem is still there, Probably worth checking whether your are using correct alias while using the cert in keystore. in my case, due to having multiple cert entry, i entered incorrect alias(in fact one with Entry type: trustedCertEntry which caused issue. while you should use one with Entry type: PrivateKeyEntry
for that just check the existing cert using
keytool -list -keystore "$JKS_CERT_PATH" -storepass "$JKS_CERT_PASSPHRASE" -noprompt -v
Get the public certificate using openssl command:
openssl s_client -showcerts -connect iam-sso.google.net:443 </dev/null 2>/dev/null|openssl x509 -outform PEM >mycertfile.pem
Import it into the Keystore:
keytool -import -alias "new-qet-alias" -keystore /usr/share/tomcat8/webapps/ROOT/WEB-INF/classes/saml/samlKeystore.jks -file mycertfile.pem

Using a self-signed certificate

I am just trying to get my head around SSL.
I have set up a Jetty server on my localhost, and generated my own certificate using Keytool.
Now when I go to https://localhost:8443/ I get the can't trust this certificate error.
I use
keytool -export -alias pongus -keystore keystore -file certfile.cer
To create the certificate which I think is what the client needs to authenticate with the server. (This is where I could be very wrong!)
I have the following ruby code :
require 'net/https'
require 'openssl'
require 'open-uri'
puts 'yay' if File.exists?('certfile.cer')
uri = URI.parse("https://localhost:8443/")
http_session = Net::HTTP.new(uri.host, uri.port)
http_session.use_ssl = true
http_session.verify_mode = OpenSSL::SSL::VERIFY_PEER
http_session.ca_file = 'certfile.cer'
res = http_session.start do |http|
# do some requests here
http.get('/')
end
This does print 'yay', so the certfile.cer file does exist.
But I get the errors
/Applications/NetBeans/NetBeans 6.8.app/Contents/Resources/NetBeans/ruby2/jruby-1.4.0/lib/ruby/1.8/net/http.rb:586 warning: can't set verify locations
/Applications/NetBeans/NetBeans 6.8.app/Contents/Resources/NetBeans/ruby2/jruby-1.4.0/lib/ruby/1.8/net/http.rb:586:in `connect': certificate verify failed (OpenSSL::SSL::SSLError)
Any ideas what I am doing wrong?
EDIT
I want to get it so I guarantee that I am connecting to the right server, and the server can guarantee that it is me connecting to it, without any tampering in between. I am developing both the server and the client.
Your client needs access to its
private key.
You dont need the private key for server certificate verification. All you need is the certificate itself which contains the public key. Only the server has the private key. Well described here http://www.helpbytes.co.uk/https.php and here http://www.verisign.com/ssl/ssl-information-center/how-ssl-security-works/
My recommendation is simple. Check your certificate is correct.
openssl x509 -text -in mycert.crt
Also if you have access to the server you can explicitely validate if the certificate and key (used in httpd configuration) are correct (matches): http://kb.wisc.edu/middleware/page.php?id=4064 Please note this is explicit check ran on server. Never give out the private key. This check can be done only by the administrator to verify if the httpd was not misconfigured.
(openssl x509 -noout -modulus -in server.pem | openssl md5 ;\
openssl rsa -noout -modulus -in server.key | openssl md5) | uniq
You can also debug the SSL certificate communication using standard openssl command. Issue this command then wait few seconds and then type QUIT and hit enter. You will see the certificate the server sends out.
openssl s_client -connect your.server.com:443
Also try to import the certificate to your browser and access the URL resource. Browser is able to validate it by clicking on https (Firefox and Chrome). Then you will see the certificate itself and validity information.
All the above was all about the server certificate. This is only one part of the problem. "I am connecting to the right server, and the server can guarantee that it is me connecting to it" Actully in your code above you only check for the server cert. Now. If you want a client certificate (the second part of your statement) than you need this in Ruby:
File.open( "client_certificate.pem", 'rb' ) { |f| cert = f.read }
File.open( "client_key.pem", 'rb' ) { |f| key = f.read }
http_session.cert = OpenSSL::X509::Certificate.new(cert)
http_session.key = OpenSSL::PKey::RSA.new(key, nil)
This is how client cert should be used in Ruby. If your private key is encrypted with a password just pass it instead nil in the second argument of RSA constructor.
I highly recommend to get server certificate working (your code) and then start with client certificate. Please note you keep your current code (ca_cert, validation constant) and add the above four lines to it.
Hope this helps.
Your client needs access to its private key. The private key is not in the certificate, the certificate only contains the public key. Sorry, I don't know ruby, but a common technique is to bundle the private key and certificate in a single PKCS#12, aka p12, file and supply this to the crypto library.
Change
http_session.verify_mode = OpenSSL::SSL::VERIFY_PEER
to
http_session.verify_mode = OpenSSL::SSL::VERIFY_NONE
Once you do that, the SSL will work properly. I have used this multiple times in my development environments, always works flawlessly.

Resources