I can send notifications to my iPhone device succeffully using Push Sharp via sandbox APNS server but I am having a problem.
I have generated .cer and .p12 files and then installed them on my windows 8 development machine successfully.
I used this tutorial to install the certificates on my windows 8 machine.
Yesterday things were working fine and I was sending the notification successfully. I shutdown my system and then next day when I try to run the code I was getting following exception:
the message was unexpected or badly formatted pushsharp
I tried different solution available on Google but nothing helped. Then I delete the certificates from my machine and then re-install them and things started to work again.
In order to make the service fool proof I shutdown the system to check if notification sending fails or not, and yes it fail again with the same exception.
I again deleted the certificates and re-install them to correct the issue. I do not know whats the actuall problem? what makes PUSHSharp to stop sending notification after shutdown.
Note: Windows firwall is disabled.
Any idea?
I have been working with PushSharp for the past few weeks and have not had this problem. My environment is Windows 7 however. After you've created the appropriate Push Notification Certificate in iPhone Developer Program Portal you should have downloaded a file named something like apn_developer_identity.cer. If you have not done so already, you should open/import this file into Keychain, into your login section.
Finally, if you filter Keychain to show your login container's Certificates, you should see your Certificate listed. Expand the certificate, and there should be a Key underneath/attached to it.
Right Click or Ctrl+Click on the appropriate Certificate and choose Export. Keychain will ask you to choose a password to export to. Pick one and remember it. You should end up with a .p12 file. You will need this file and the password you picked to use the Notification and Feedback Libraries here.
OpenSSL
Here is how to create a PKCS12 format file using open ssl, you will need your developer private key (which can be exported from the keychain) and the CertificateSigningRequest??.certSigningRequest
Convert apn_developer_identity.cer (der format) to pem:
openssl x509 -in apn_developer_identity.cer -inform DER -out apn_developer_identity.pem -outform PEM}
Next, Convert p12 private key to pem (requires the input of a minimum 4 char password):
openssl pkcs12 -nocerts -out private_dev_key.pem -in private_dev_key.p12
(Optional): If you want to remove password from the private key:
openssl rsa -out private_key_noenc.pem -in private_key.pem
Take the certificate and the key (with or without password) and create a PKCS#12 format file:
openssl pkcs12 -export -in apn_developer_identity.pem -inkey private_key_noenc.pem -certfile CertificateSigningRequest??.certSigningRequest -name "apn_developer_identity" -out apn_developer_identity.p12
Once you generate the p12 file using these steps you will not really need to snap it to your console. You will just need to make changes in your code as follows:
var appleCert = File.ReadAllBytes("C:/Certificate/aps_dev_identity.p12");
Hope this helps.
I have been working on MOON APNS since 2012 and it's working fine but from last few days i am getting below error message
Error Message : System.Security.Authentication.AuthenticationException: A Call to SSPI failed, see inner exception.
System.ComponentModel.Win32Exception: The message received was
unexpected or badly formatted
Solution : in PushNotification.cs file replace
_apnsStream.AuthenticateAsClient(host, certificates, System.Security.Authentication.SslProtocols.Ssl3, false);
with
_apnsStream.AuthenticateAsClient(host, certificates, System.Security.Authentication.SslProtocols.Tls, false);
As, I didn't find any confirmation from apple side but from github.com I found solution for this and it's work for us.
It's seems that apple depricate "unsafer" protocol SSL.
Check first if you can do the notifications with C# code like this one first, then worry about the installation. I had the same message when I was trying to execute the code, I didn't care about installation, and solved it by making sure that I use a certificate of type .p12 and not .pem and to make sure that the .p12 had a password. I can now send notifications to my iPhone from a console C# app in my pc.
Related
I have been trying to log in to a Betfair account following these steps and using this source code. This works fine and I am returned a session key, however if I try to repeat the steps to get a session key in another project I receive a "CERT_AUTH_REQUIRED" error, implying that there is something wrong with the client certificate I am sending with my request.
Odder still, if I create another project that references the working Betfair project and get this new project to simply run the Program.Main method in the Betfair project I get the "CERT_AUTH_REQUIRED" message again?
When the Betfair application is the Launch project for the solution it works, but if I set the second project that launches the betfair console app as the startup project it doesn't return a success response (although the code runs fine and goes through all the same steps, it is just the web response that fails).
Does anyone have any idea why this might be?
I managed to get that code working for non-interactive log ins. I did make this change though. It sounds vaguely familiar as I remember having that error.
private WebRequestHandler getWebRequestHandlerWithCert(string certFilename)
{
var cert = new X509Certificate2(certFilename, "", X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable);
var clientHandler = new WebRequestHandler();
clientHandler.ClientCertificates.Add(cert);
return clientHandler;
}
Another thing that I've just found can cause the same error is if you enter an export password during the step below. That may have changed since you created your key because it marks it as exportable so I didn't need to add X509KeyStorageFlags.Exportable in the code:
openssl pkcs12 -export -in client-2048.crt -inkey client-2048.key -out client-2048.p12
I assumed the export password was what the sample application was prompting for but it wasn't so the export password should be left blank.
I'm developing an application using Secure Sockets in Unity5 (in C#) to allow a server to push information to clients. I want to use Socket and SSLStream for this, to keep the communications secure.
I have an elastic beanstalk environment setup with a certificate provided by the AWS certificate service.
I've written a client class that can connect to this environment with a RemoteCertificateValidationCallback below:
public static bool RemoteCertificateValidationCallback(System.Object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
{
bool isOk = true;
// If there are errors write them out
if (sslPolicyErrors != SslPolicyErrors.None)
{
//Debug.Log(sslPolicyErrors.ToString());
Console.WriteLine(sslPolicyErrors.ToString());
return false;
}
return isOk;
}
When I run this code from a Console application created in Visual Studio 2017 I get sslPolicyErrors.None as expected.
Running the exact same code from within Unity5 (minus Console references) gives me sslPolicyErrors.RemoteCertificateNotAvailable.
I've tried importing the certificates to the Mono trust store using mozroots -import --machine which gives the following output:
Issuer: C=US, O=Amazon, OU=Server CA 1B, CN=Amazon
Serial number: 66-xx-xx-xx-xx-xx-xx-xx-xx-xx-46-xx-xx-xx-xx-0D
Valid from 05/05/2017 00:00:00 to 05/06/2018 12:00:00
I've been hunting around but can find nothing that would suggest why this works as a standalone console program, but not when run from Unity. If I ignore this sslPolicyError specifically, everything works just fine, communication between the client and server happens as expected. But I don't want to be randomly ignoring an error that could mean the communications could be compromised.
I'm really hoping someone here has some idea!
why this works as a standalone console program, but not when run from Unity?
As Mono official said, Mono doesn’t include root certificates while standalone program using system certs.
There is one solution that install the cert via X509Store.
string cert = "BASE64 ENCODED CERT(PEM), NOT HEADER AND FOOTER, BASICALLY EXPORTED BY OPENSSL";
byte[] certBytes = Convert.FromBase64String(cert);
X509Certificate2 certificate = new X509Certificate2(cert);
X509Store store = new X509Store(StoreName.Root, StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadWrite);
store.Add(certificate);
store.Close();
You can use openssl to export a pem, like openssl x509 -inform DER -in YOUR_CER.cer -out YOUR_PEM.pem.
Once the proper cert is installed, RemoteCertificateValidationCallback won't return RemoteCertificateNotAvailable anymore if connecting to trusted sites.
I have been attempting to create an SSL server that loads a certificate from a .crt. I have tried both X509Certificate.CreateFromCertFile(#".\Secure\Certificate\" + CertName + ".crt"); and the cert.import, and neither works. On both, I get an issue saying "The server mode SSL must use a certificate with the associated private key". And the key is there! My directory:
Secure/
Certificate/
ZeusHTTP.crt
ZeusHTTP.csr
ZeusHTTP.key
Plugins/
...
The certs are created with OpenSSL.
A simple read of the docs tells us that you should be using a pkcs7 file that usually has file suffix p7b. You'll need to either convert your OpenSSL cert to this format, or find a utility that can generate one from scratch.
The server mode SSL must use a certificate with the associated private key". And the key is there...
As other have stated, they must be in the same file. Here are the steps to do it.
First
Copy ZeusHTTP.crt to ZeusHTTP-chain.crt:
cp ZeusHTTP.crt ZeusHTTP-chain.crt
Second
Open ZeusHTTP-chain.crt and ensure it has all the intermediates certificates required to validate the server certificate. So you will have 2 or more certificates:
-----BEGIN CERTIFICATE-----
<server certificate>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<intermediate certificate>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<intermediate certificate>
-----END CERTIFICATE-----
Add certificates as required. For example, if you got a free Startcom certificate, then you need to add the sub.class1.server.ca.pem intermediate from StartSSL's Index of Certs.
Sending all certificates is required to solve the "which directory" problem in PKI. Its a well known problem in PKI, and essentially it means a client does not know where to go to fetch missing intermediate certificates.
Third
Perform the following to generate a PKCS 12 file:
openssl pkcs12 -export -in ZeusHTTP-chain.crt -inkey ZeusHTTP.key -out ZeusHTTP.p12
Fourth
Finally, install the certificate on IIS as a test.
For your code, I believe you need to load it into a Certificate2 and not a Certificate.
Also see How to read a .p12 file in my web service on Stack Overflow and how to create x509 certificate and use it in sslstream on MSDN.
I'm currently trying to create a chat based on the SslStream class.
I was going through that msdn link: click here
I realized that I need to get an X509Certificate to establish that task. But I really don't know how can I get one? I know that there are ones who cost money, but there aren't free ones available?
P.S: I'm coming here after doing some search in google about that subject but haven't found any helpfull infomation.
So my question is: Where can I get an x509 certificate?
Thank you.
You can create certificates with the makecert tool.
Or, if your're only interested in encrypting the traffic, without signing it, and you control the client and the server, just use a CryptoStream.
You can generate your own, and sign it yourself, using openssl, though keep in mind if the client tries to verify it, and by client I usually mean the browser, since this is their most common use, though not the only one, they won't be able to.
I know that there are ones who cost money, but there aren't free ones available?
Basically what you are paying for is for a CA, certificate authority to sign it, as such when clients go and verify who you are with with CA it'll pass.
openssl: http://www.openssl.org/
This is the command I ussually use openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout server.key -out server.pem
server.pem is your certificate and server.key is your private key.
Giving that you probably already have .NET SDK installed maybe makecert is a better/eassier approach since you would need to build openssl.
Stil I went to their docs and I couldn't find how to set the key size, though apparently the default is 1028 and I think using RSA , but I did find this:
makecert -pe -ss MY -$ individual -n "CN=your name here" -len 2048 -r
from MakeCert - Is it possible to change the key size? to http://www.mazecomputer.com/sxs/help/shared.htm
openssl supports many types not just RSA but maybe you don't need them.
These guys http://www.cacert.org/ have been giving away free certificates for years.
Read through this for clarity. You can sign your public key using Symantec's Verisign service. It is definitely not cheap. For testing, you can make your own certificate using a dummy CA.
I'm using the SSLStream example from msdn here. The client code "seems" to work fine, as I can connect to google and it at least gets past authentication, but the server doesn't.
From the comments from the msdn page, I used the procedure on this page to generate my own private key, but it just doesn't work. I get an exception of System.NotSupportedException: The server mode SSL must use a certificate with the associated private key. So I'm pretty sure whatever I'm doing is wrong.
So my question is simple: how do I get/generate keys that will work for my own little example program from msdn? It can be self-signed, whatever, but I'm too new to SSL to even know what exactly I need. All I want to do is to run the example as-given, except for specifying my own certificates for my local server. And it'd be great to know what I'd have to install on my 2nd machine if I just want to communicate between the two of them too (so it's not a 100% localhost example).
Personally I see this as a flaw in the example document. It should say "to run this, you need to do A, B, C, etc," but it doesn't.
You can get the example to work even with self-signed certificates. I've extracted the commands from the makecert tutorial that you're using with minor modifications:
makecert -sv RootCATest.pvk -r -n "CN=FakeServerName" RootCATest.cer
makecert -ic RootCATest.cer -iv RootCATest.pvk -n "CN=FakeServerName" -sv TempCert.pvk -pe -sky exchange TempCert.cer
cert2spc TempCert.cer TempCert.spc
pvkimprt -pfx TempCert.spc TempCert.pvk
makecert and cert2psc can be found in your Microsoft SDKs\Window\v7.0A\Bin folder.
The pvkImport.exe installer can be downloaded here (Provided by #Jospeph and VirusTotal verified). This used to be downloadable from the Microsoft Site, but they have since taken it down. Alternatively, #Dweeberly pointed us to a new Microsoft-provided replacement, pvk2pfx.
For this next step make sure that you select to EXPORT the private key when the dialog from pvkimprt comes up:
pvkimprt -pfx TempCert.spc TempCert.pvk
pvkimprt will prompt you for a password when you elect to include the private key. You will need to provide this password later when you import the generated .pfx file into the personal store of your server machine
Next, import RootCATest.cer into your Computer store's Trusted Root Certification Authorities (on both the server and client). Notice that the certificate is issued to FakeServerName. This must match the server name that the SslTcpClient expects: sslStream.AuthenticateAsClient(serverName), where serverName is the value of the second argument passed to SslTcpClient.exe.
When your client connects, the server presents a certificate that tells the client "I'm FakeServerName". The client will accept this claim if the client machine trusts the CA that issued the certificate, which is achieved by importing RootCATest.cer into the client's Trusted Root Certification Authorities.
Finally, you need to import the private key that the server is going to use into the server machine's Personal store. This step is important because it addresses The server mode SSL must use a certificate with the associated private key.. This is achieved by importing the .pfx file that you generated earlier. Make sure that you change the file type filter to "all files" so that you can see the .pfx file that you generated:
The sample code provided by MSDN uses port 443 (which is the standard ssl port). Since I created console applications, I changed the port used by the sample classes to 8080:
SslTcpServer:
TcpListener listener = new TcpListener(IPAddress.Any, 8080);
SslTcpClient:
TcpClient client = new TcpClient(machineName, 8080);
Here's the output:
you would launch your server like this:
SslTcpServer.exe TempCert.cer
from the client, you would connect like this:
SslTcpClient.exe <ip to your server> FakeServerName
generate your certificate using this command:
makecert -r -pe -n "CN=localhost" -m 12 -sky CertSubject -ss my serverCert.cer
and then from client connect to the server like this (assuming we are using MSDN example you mentioned):
SslTcpClient.RunClient ("localhost", "CertSubject");
you will get validation errors in ValidateServerCertificate() call - but that's expected - you are using self-signed certificate. Just return true there.
UPDATE:
I disagree with Tung's suggestion of adding self-signed certificate into the client's Trusted Root Certification Authorities. I think it can cause issues later on if you plan to distribute/support your software. For example, client might reinstall windows, or move his profile to another PC, or whatever - and understanding WHY your software suddenly stopped working will be a pain (again, i'm talking long-term - a year or two from now, when you completely forget this little "trick").
Instead i would rather suggest to "hardcode" your certificate (by comparing subject and thumbprint) into client's logic, something like this:
X509Certificate2 certificate = (X509Certificate2)cert;
if (certificate.Subject.StartsWith("CN=FAKE_SERVER_WHATEVER") &&
!string.IsNullOrEmpty(certificate.Thumbprint) &&
certificate.Thumbprint.ToLower() == "11c4446c572a9918ced3618728b91b3a07982787")
{
return true;
}
return false;
As the Microsoft link to download pvkimprt is broken and I am a fan of OpenSSL here I leave two solutions with OpenSSL.
VARIANT #1 - Self Signed Certificate
First you will need download OpenSSL and this configuration file. #Tung has said you can use perfectly self-signed certificate. Copy the downloaded configuration file in the same folder where you will run OpenSSL commands.
Lets generate the private key and certificate of Certification Authority:
openssl req -x509 -config openssl.cnf -newkey rsa:4096 -sha256 -out ssl-cacert.pem -keyout ssl-cakey.pem -outform PEM
*Use -nodes parameter to omit the passphrase, but for safety reasons personally I do not recommend it.
If you desire inspect the information of CA certificate, execute the follow command:
openssl x509 -purpose -in ssl-cacert.pem -inform PEM
Lets create the certificate request, Common Name must be set with the machine name:
openssl req -config openssl.cnf -newkey rsa:2048 -keyout ssl-serverkey.pem -sha256 -out ssl-server.csr -outform PEM
*Same note for -nodes parameter.
If you want inspect the certificate request information execute the command:
openssl req -text -noout -verify -in ssl-server.csr
Sign the certificate request with the generated CA certificate:
openssl x509 -req -days 365 -CA ssl-cacert.pem -CAkey ssl-cakey.pem -CAcreateserial -in ssl-server.csr -out ssl-server-certificate.pem
Lets make the self-signed certificate with PFX format:
openssl pkcs12 -export -out ssl-certificate.pfx -inkey ssl-serverkey.pem -in ssl-server-certificate.pem -certfile ssl-cacert.pem -name "SSL Self Signed Certificate"
Now you should import the .pfx certificate.
Double click on ssl-certificate.pfx file.
Select "Local Machine" option and Next.
Type the password and select the checkbox "Mark this key as exportable."
Select the radio button "Place all certificates in the following store".
Select Personal store and click in Next.
With this steps must work.
VARIANT #2 - Generate CA Certificate and Server Certificate
Personally I prefer this solution over the first because only I have to distribute the Root CA certificate to the clients.
First download this configuration file.
We will generate the Root CA certificate with the corresponding private key:
openssl req -x509 -config openssl.cnf -newkey rsa:4096 -sha256 -keyout ssl-cakey.pem -out ssl-cacert.pem -outform PEM
Lets check certificate properties:
openssl x509 -purpose -in ssl-cacert.pem -inform PEM
The information must show should look like this:
Certificate purposes:
SSL client : No
SSL client CA : Yes
SSL server : No
SSL server CA : Yes
Netscape SSL server : No
Netscape SSL server CA : Yes
S/MIME signing : No
S/MIME signing CA : Yes
S/MIME encryption : No
S/MIME encryption CA : Yes
CRL signing : Yes
CRL signing CA : Yes
Any Purpose : Yes
Any Purpose CA : Yes
OCSP helper : Yes
OCSP helper CA : Yes
Time Stamp signing : No
Time Stamp signing CA : Yes
-----BEGIN CERTIFICATE-----
MIIGLjCCBBagAwIBAgIJANCzs7UBFJMpMA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNV
...
im1yDnB5nPwkPwZ9eRmlzIc6OaLZcfbFfSeSw8/ipKZcEJ1u+EFrB0JhuSbeLXtQ
N/8=
-----END CERTIFICATE-----
Create the certificate request with the following command:
openssl req -config openssl.cnf -newkey rsa:2048 -sha256 -keyout ssl-serverkey.pem -out ssl-servercert.csr -outform PEM
It's very important set the Common Name with the machine name of server.
Verify the information of this certificate request:
openssl req -text -noout -verify -in ssl-servercert.csr
The information shows must have the following format, check that the CN field in the section Subject is the name of server machine.
verify OK
Certificate Request:
Data:
Version: 0 (0x0)
Subject: C=US, ST=..., L=..., O=..., OU=..., CN=SERVERNAME
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:aa:92:bd:87:75:18:6c:c0:23:3f:0b:5a:46:1a:
...
fe:13
Exponent: 65537 (0x10001)
Attributes:
Requested Extensions:
X509v3 Subject Key Identifier:
7E:7D:79:F4:CD:71:0E:90:3A:9A:F8:3F:83:7D:89:90:4D:D4:F0:12
X509v3 Basic Constraints:
CA:FALSE
X509v3 Key Usage:
Digital Signature, Key Encipherment, Data Encipherment
Signature Algorithm: sha256WithRSAEncryption
34:e1:b4:db:b2:87:cc:11:3e:85:3c:ed:ac:8d:d9:43:ae:b0:
...
56:84:29:f9
Create the certificates folder:
mkdir certificates
Create the database index file:
Windows: type NUL > index.txt
Unix: touch index.txt
Create the serial.txt file where is stored the current serial number:
echo '01' > serial.txt
Create the server certificate signing the certificate request for 2 years with the command. You will be prompted the pass phrase of CA certificate depending if you used -nodes parameter:
openssl ca -config openssl.cnf -days 730 -policy signing_policy -extensions v3_req -out ssl-servercert.pem -infiles ssl-servercert.csr
Then is displayed a text with the format:
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'US'
stateOrProvinceName :ASN.1 12:'...'
localityName :ASN.1 12:'...'
organizationName :ASN.1 12:'...'
organizationalUnitName:ASN.1 12:'...'
commonName :ASN.1 12:'SERVERNAME'
Certificate is to be certified until Jul 4 23:26:59 2018 GMT (730 days)
Sign the certificate? [y/n]:
Select y and will prompted the follow text, select y one more time:
1 out of 1 certificate requests certified, commit? [y/n]
Export the generated certificate to PFX format:
openssl pkcs12 -export -out ssl-certificate.pfx -inkey ssl-serverkey.pem -in ssl-servercert.pem -name "SSL Signed Certificate"
You will need do the follow steps to enable SSL without problem:
On Server Machine:
Import the Root CA certificate (ssl-cacert.pem file) on Trusted Root Certification Authorities store selecting Computer account.
Import Server Certificate for SSL (ssl-certificate.pfx file) on Personal store selecting Computer account.
On Client Machines:
In each client machine you will need import the Root CA certificate (ssl-cacert.pem file) on Trusted Root Certification Authorities store selecting Computer account.
Feel free to make any changes or suggestions.