I am using notnoop APNS 0.2.3, was struggling with the certs, and now I am struggling with SSL.
There is no documentation on how to prepare a p12 file for the library, so I found this article to guide me.
service = APNS.newService()
.withCert(mycertPath, myP12password)
.withSandboxDestination()
.build();
service.start();
service.testConnection();
service.push(listOfTokens,payload);
The start method fails with the following dump
09:46:16,657 INFO ~ Failed to send message Message(Token=00; Payload=)... trying again after delay
javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:136)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1822)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1004)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1188)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:654)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(AppOutputStream.java:100)
at java.io.OutputStream.write(OutputStream.java:58)
at com.notnoop.apns.internal.ApnsConnectionImpl.sendMessage(ApnsConnectionImpl.java:240)
at com.notnoop.apns.internal.ApnsConnectionImpl.sendMessage(ApnsConnectionImpl.java:230)
at com.notnoop.apns.internal.ApnsConnectionImpl.testConnection(ApnsConnectionImpl.java:294)
at com.notnoop.apns.internal.ApnsServiceImpl.testConnection(ApnsServiceImpl.java:57)
Did I screw up the p12 file? Is there something else I am missing here?
[UPDATE 1]
I am trying the following script to create and test the p12 file command line, and am also getting a connection error, so there is something I likely messed up in the certificates.
[UPDATE 2]
I altered the script to create p12 files... incase others can benefit from this.
#!/bin/sh
bold=`tput bold`
normal=`tput sgr0`
# CONVERT CERT TO PEM
echo "${bold}CONVERTING${normal} APNS..."
openssl x509 -in aps_development.cer -inform der -out aps_development.pem
openssl x509 -in aps_production.cer -inform der -out aps_production.pem
# CONVERT PRIVATE KEY P12 INTO PEM
echo "${bold}CONVERTING ${normal} private key..."
openssl pkcs12 -nocerts -out my_private.pem -in my_private.p12
# COMBINE CERTS INTO SINGLE P12
echo "${bold}COMBINING ${normal} development..."
#cat aps_development.pem my_private.pem > my_development.pem
openssl pkcs12 -export -in aps_development.pem -inkey my_private.pem -out my_development.p12
# COMBINE CERTS INTO SINGLE P12
echo "${bold}COMBINING ${normal} production..."
#cat aps_production.pem my_private.pem > my_production.pem
openssl pkcs12 -export -in aps_production.pem -inkey my_private.pem -out my_production.p12
echo "${bold}TESTING${normal}..."
# TEST IT
openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert aps_development.pem -key my_private.pem
issue was a certificate problem and a misunderstanding that "AdHoc" only works with production push servers.
Related
I am trying to generate a self signed certificate for secured grpc communication. Below is what I have tried and connection between services work flawlessly in localhost.
However, the moment I deploy one of the services to production(Google Cloud Run) connection stops working. How can I make the certificate to support connection whether in localhost or in production.
Below is the certificate generation script I have tried.
generator.sh
# Clean Up
rm *.crt
echo "Generating certificates ..."
openssl genrsa -passout pass:1111 -des3 -out ca.key 4096
openssl req -passin pass:1111 -new -x509 -days 365 -key ca.key -out ca.crt -subj "/C=CL/ST=RM/L=Santiago/O=Test/OU=Test/CN=ca"
openssl genrsa -passout pass:1111 -des3 -out server.key 4096
openssl req -passin pass:1111 -new -key server.key -out server.csr -subj "/C=CL/ST=RM/L=Santiago/O=Test/OU=Server/CN=localhost"
openssl x509 -req -passin pass:1111 -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
openssl rsa -passin pass:1111 -in server.key -out server.key
openssl genrsa -passout pass:1111 -des3 -out client.key 4096
openssl req -passin pass:1111 -new -key client.key -out client.csr -subj "/C=CL/ST=RM/L=Santiago/O=Test/OU=Client/CN=localhost"
openssl x509 -passin pass:1111 -req -days 365 -in client.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out client.crt
openssl rsa -passin pass:1111 -in client.key -out client.key
How can I make connection between services work all the time whether in localhost or in production which in my own case is Google Cloud Run (*.run.app)?
Thank you.
Your title says "multiple Common Names in certificate" but your body effectively says (twice) "work both for localhost and other host(s)". Those are entirely different. The X.509 certificate structure is quite flexible and it is technically possible to create one with multiple CommonName attributes in Subject, but if used for SSL/TLS (including HTTPS) only one of them will actually be considered when determining certificate validity; see rfc2818 and rfc6125.
There are two ways to have a certificate usable for multiple server names, which can actually be multiple names for one server (common in virtual hosting) or different servers (your case):
use a wildcard name. If you make all your machines have names which vary only in the first DNS label, such as the pattern you posted *.run.app, you can use one CommonName containing that wildcard. If your 'localhost' is actually your own computer or VM, you can use /etc/hosts or a local DNS like dnsmasq or unbound to assign it a name matching this pattern such as myownmachine.run.app and that will work with this certificate.
use the Subject Alternative Name/SAN extension which can contain multiple values each of which is either a DNS name or wildcard or an IP address (you probably don't want the latter, but it's available). All certs from real (public) CAs have used SAN since about 2010. For SAN in OpenSSL, see to start
Add SAN with private CA
Requested Extensions in CSR not being reflected in CRT
Self signed SSL certificate: Subject Alternative Name (SAN) gets lost when signing
https://security.stackexchange.com/questions/204036/specify-subject-alt-names-in-openssl
https://security.stackexchange.com/questions/190905/subject-alternative-name-in-certificate-signing-request-
https://security.stackexchange.com/questions/150078/missing-x509-extensions-with-an-openssl-generated-certificate
https://security.stackexchange.com/questions/74345/provide-subjectaltname-to-openssl-directly-on-command-line
From AWS tech talk, I have learnt that,
I am able to create private server certificate using below option:
-------------------
The server certificates serve the rationale of encrypting and decrypting the content.
Whereas
client certificate as the name implies is clearly used to identify a client to a respective user
A device certificate creates an identity for each “thing” in an IoT ecosystem,
making sure each device authenticates as it connects, and protects communication between devices.
We have created root CA and subordinate CA using AWS Cert mgr through console.
How to create device & client certificate(private) using ACM GoLang sdk?
[UPDATE after question asked for ACM]
Use the aws acm-pca issue-certificate command to request a certificate:
CLIENT_ID="device-0001"
CLIENT_SERIAL=0001
# Create the CSR and Private Key
openssl req -new -newkey rsa:2048 -days 365 -keyout ${CLIENT_ID}.key -out ${CLIENT_ID}.csr
# Replace --certificate-authority-arn with your ARN returned when you create the certificate authority.
aws acm-pca issue-certificate \
--csr file://${CLIENT_ID}.csr \
--signing-algorithm "SHA256WITHRSA" \
--validity Value=375,Type="DAYS" \
--idempotency-token 12983 \
--certificate-authority-arn arn:aws:acm-pca:region:account:\
certificate-authority/12345678-1234-1234-1234-123456789012
This command outputs the ARN, save this value for the next command ($MY-CERT-ARN)
aws acm-pca get-certificate \
--certificate-authority-arn arn:aws:acm-pca:region:account:\
certificate-authority/12345678-1234-1234-1234-123456789012 \
--certificate-arn $MY-CERT-ARN \
--output text > ${CLIENT_ID}-cert.pem
[END UPDATE]
Example code to generate a client certificate. Change CLIENT_ID and CLIENT_SERIAL for each certificate that you generate. ca.pem and ca.key are your CA certificate and private key.
CLIENT_ID="device-0001"
CLIENT_SERIAL=0001
openssl genrsa -aes256 -passout pass:xxxx -out ${CLIENT_ID}.pass.key 4096
openssl rsa -passin pass:xxxx -in ${CLIENT_ID}.pass.key -out ${CLIENT_ID}.key
rm ${CLIENT_ID}.pass.key
# generate the CSR
openssl req -new -key ${CLIENT_ID}.key -out ${CLIENT_ID}.csr
# issue this certificate, signed by the CA (ca.pem ca.key)
openssl x509 -req -days 375 -in ${CLIENT_ID}.csr -CA ca.pem -CAkey ca.key -set_serial ${CLIENT_SERIAL} -out ${CLIENT_ID}.pem
# Give the client the file: ${CLIENT_ID}.full.pem
cat ${CLIENT_ID}.key ${CLIENT_ID}.pem ca.pem > ${CLIENT_ID}.full.pem
I am looking for ruby code to mimic below openssl smime encryption. I looked up other related topics but mostly were around signing. In snippet below cert.pem is a PEM-encoded X.509 certificate containing the PEM public key. token.txt file is the file to be encrypted.
openssl smime -encrypt -out encrypted.p7m -in token.txt cert.pem
Figured it.
token_plain_text = File.read("/path/to/token.txt")
cert = X509::Certificate.new("/path/to/cert.pem")
encrypted_object = OpenSSL::PKCS7.encrypt([cert], token_plain_text)
Got the encrypted string by outputting above object to string.
encrypted_str = encrypted_object.to_str
This has me confused:
Convert pfx to PEM:
openssl pkcs12 -in certificatename.pfx -out certificatename.pem
Do this dumps out a single plain text file.
Now how do I convert this plain text pem back to pfx?
The only commands I see to convert to pfx require the cer and private keys in separate files:
Convert CER and Private Key to PFX:
openssl pkcs12 -export -in certificatename.cer -inkey privateKey.key -out certificatename.pfx -certfile cacert.cer
Although I concur this is not really programming and arguably offtopic, numerous similar Qs about commandline tools (openssl, keytool, certutil etc) for (crypto) keys and certs are apparently accepted by the community (upvoted) -- but none I've seen directly addresses this point.
The different options on openssl pkcs12 -export allow you to provide the pieces in different files, but that is not required. If you do have the privatekey and chain of certs in one PEM file, as output by default by pkcs12 [not -export], you can let everything be read from that one file:
openssl pkcs12 -export -in file -out p12
# or ONLY IF the privatekey is first in the file
openssl pkcs12 -export <file -out p12
and you can even combine the pieces 'on the fly' as long as you put privatekey first:
cat privkey.pem mycert.pem chain.pem | openssl pkcs12 -export -out p12
You can use the command below to convert PEM (.pem, .crt, .cer) to PFX:
openssl pkcs12 -export -out **<your_new_file_name>**.pfx -inkey **<private_key_of_your_existing_certificate>**.key -in **<your_existing_certificate_file>**.crt
This will be very generic for all above mentioned files.
Is there a way in Ruby to digitally sign email messages with S/MIME? Our group uses PKI and our users are conditioned to expect digital signatures for important messages.
I know I can invoke the openssl command line tool:
openssl smime -sign -signer $CERT_FILE -passin pass:$CERT_PASS
-in $UNSIGNED_MAIL -out $SIGNED_MAIL -certfile $CERT_CA_FILE
-from 'your ' -to 'recipients <email#address>'
-subject 'The Subject'
but I am hoping to utilize a Ruby solution.
I ended up using the above solution, but for those in a similar situation, you have to convert the PKI key (in .p12 file format) first: openssl pkcs12 -in #{#cert_file} -passin pass:#{#pass_phrase} -passout pass:#{#pass_phrase} -out #{out_file}