Created
November 13, 2015 11:58
-
-
Save davidvesely/fed58351ee1b98c37cbc to your computer and use it in GitHub Desktop.
Подписване на заяка към сървис без ръчно въвеждане на ПИН код в SmartCard устройство със сертификат
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using Net.Pkcs11Interop.Common; | |
| using Net.Pkcs11Interop.HighLevelAPI; | |
| using Net.Pkcs11Interop.PDF; | |
| using Org.BouncyCastle.Crypto.Parameters; | |
| using System; | |
| using System.Collections.Generic; | |
| using System.IO; | |
| using System.Linq; | |
| using System.Net; | |
| using System.Net.Security; | |
| using System.Security; | |
| using System.Security.Cryptography; | |
| using System.Security.Cryptography.X509Certificates; | |
| using System.Text; | |
| using System.Threading.Tasks; | |
| using System.Xml; | |
| namespace NssiReport.Test | |
| { | |
| public static class Program | |
| { | |
| static void Main(string[] args) | |
| { | |
| Console.WriteLine("Press key to continue with the request to NSSI"); | |
| Console.ReadKey(); | |
| X509Certificate2 cert = null; | |
| var store = new X509Store(StoreLocation.CurrentUser); | |
| store.Open(OpenFlags.ReadOnly); | |
| var certificates = store.Certificates.Find(X509FindType.FindBySerialNumber, Settings.Default.SerialNumber, false); | |
| cert = certificates[0]; | |
| RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey; | |
| CspParameters cspp = new CspParameters(); | |
| cspp.KeyContainerName = rsa.CspKeyContainerInfo.KeyContainerName; | |
| cspp.ProviderName = rsa.CspKeyContainerInfo.ProviderName; | |
| // cspp.ProviderName = "Microsoft Smart Card Key Storage Provider"; | |
| cspp.ProviderType = rsa.CspKeyContainerInfo.ProviderType; | |
| //cspp.Flags = CspProviderFlags.NoPrompt; | |
| cspp.KeyPassword = CreatePasswordKey(Settings.Default.PinCode); | |
| RSACryptoServiceProvider rsa2 = new RSACryptoServiceProvider(cspp); | |
| rsa.PersistKeyInCsp = true; | |
| short report = Settings.Default.ReportType; | |
| string egn = Settings.Default.EGN; | |
| //string res = GetReport(egn, report, cert); | |
| try | |
| { | |
| NssiDataService.ServiceSoapClient client = new NssiDataService.ServiceSoapClient(); | |
| client.ClientCredentials.ClientCertificate.Certificate = cert; | |
| var result = client.GetData("Easycredit1", report, "", 2013, 2015, 1, 1, egn); | |
| if (result != null) | |
| { | |
| using (System.Xml.XmlWriter writer = System.Xml.XmlWriter.Create("result.xml")) | |
| { | |
| result.WriteTo(writer); | |
| Console.WriteLine(result.ToString()); | |
| } | |
| } | |
| else | |
| { | |
| Console.WriteLine("No result"); | |
| } | |
| } | |
| catch (Exception ex) | |
| { | |
| Console.WriteLine(ex); | |
| Console.ReadKey(); | |
| throw; | |
| } | |
| } | |
| private static SecureString CreatePasswordKey(string pin) | |
| { | |
| var pasword = new SecureString(); | |
| foreach (var c in pin) | |
| { | |
| pasword.AppendChar(c); | |
| } | |
| return pasword; | |
| } | |
| #region Legacy calls | |
| private static string GetReport(string egn, short report, X509Certificate2 certificate) | |
| { | |
| string result; | |
| var request = GetNewReportRequest(egn, report, certificate); | |
| using (var webResponse = request.GetResponse()) | |
| using (var streamReader = new StreamReader(webResponse.GetResponseStream(), UTF8Encoding.UTF8)) | |
| { | |
| result = streamReader.ReadToEnd(); | |
| } | |
| return result; | |
| } | |
| public static HttpWebRequest GetNewReportRequest(string socialSecurityNumber, short noiReportType, X509Certificate2 cert) | |
| { | |
| //Create request | |
| var request = (HttpWebRequest)WebRequest.Create("https://bwsapplications.nssi.bg/getdata.asmx"); | |
| request.Headers.Add("SOAPAction", "https://bwsapplications.nssi.bg/GetData"); | |
| request.ContentType = "text/xml;charset=\"utf-8\""; | |
| request.Accept = "text/xml"; | |
| request.Method = "POST"; | |
| //Set ServicePointManager | |
| ServicePointManager.ServerCertificateValidationCallback = | |
| (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors policyErrors) => true; | |
| ServicePointManager.Expect100Continue = true; | |
| ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | |
| | SecurityProtocolType.Tls11 | |
| | SecurityProtocolType.Tls12 | |
| | SecurityProtocolType.Ssl3; | |
| //Add Envelope | |
| var soapEnvelopeXml = GetReportSoapEnvelope(socialSecurityNumber, noiReportType); | |
| using (var stream = request.GetRequestStream()) | |
| { | |
| soapEnvelopeXml.Save(stream); | |
| } | |
| //Add Certificate | |
| if (cert != null) | |
| { | |
| request.ClientCertificates.Add(cert); | |
| } | |
| return request; | |
| } | |
| public static XmlDocument GetReportSoapEnvelope(string socialSecurityNumber, short reportType) | |
| { | |
| var soapEnvelope = new XmlDocument(); | |
| var envelopeString = @"<?xml version=""1.0"" encoding=""utf-8""?> | |
| <soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/""> | |
| <soap:Body> | |
| <GetData xmlns=""https://bwsapplications.nssi.bg""> | |
| <ExternalUserName>Easycredit1</ExternalUserName> | |
| <RepNo>" + reportType + @"</RepNo> | |
| <bulstat></bulstat> | |
| <FromYear>2015</FromYear> | |
| <ToYear>2015</ToYear> | |
| <FromMonth>6</FromMonth> | |
| <ToMonth>11</ToMonth> | |
| <EGN>" + socialSecurityNumber.Trim() + @"0</EGN> | |
| </GetData> | |
| </soap:Body> | |
| </soap:Envelope>"; | |
| soapEnvelope.LoadXml(envelopeString); | |
| return soapEnvelope; | |
| } | |
| #endregion | |
| private static void TokenExplorer() | |
| { | |
| using (Pkcs11Explorer pkcs11Explorer = new Pkcs11Explorer("bit4ipki_x64.dll")) | |
| { | |
| string tokenSerial = "1020000000050957"; | |
| string tokenLabel = null; | |
| string pin = "78963"; | |
| // Find requested token | |
| Token foundToken = null; | |
| List<Token> tokens = pkcs11Explorer.GetTokens(); | |
| foreach (Token token in tokens) | |
| { | |
| if (!string.IsNullOrEmpty(tokenLabel)) | |
| if (0 != String.Compare(tokenLabel, token.Label, StringComparison.InvariantCultureIgnoreCase)) | |
| continue; | |
| if (!string.IsNullOrEmpty(tokenSerial)) | |
| if (0 != String.Compare(tokenSerial, token.SerialNumber, StringComparison.InvariantCultureIgnoreCase)) | |
| continue; | |
| foundToken = token; | |
| break; | |
| } | |
| if (foundToken == null) | |
| throw new TokenNotFoundException(string.Format("Token with serial \"{0}\" and label \"{1}\" was not found", tokenSerial, tokenLabel)); | |
| // Get private keys and certificates stored in requested token | |
| List<PrivateKey> privateKeys = null; | |
| List<Certificate> certificates = null; | |
| pkcs11Explorer.GetTokenObjects(foundToken, true, pin, out privateKeys, out certificates); | |
| // Print private keys | |
| int j = 1; | |
| foreach (PrivateKey privateKey in privateKeys) | |
| { | |
| Console.WriteLine(); | |
| Console.WriteLine("Private key no." + j); | |
| Console.WriteLine(" ID (CKA_ID): " + privateKey.Id); | |
| Console.WriteLine(" Label (CKA_LABEL): " + privateKey.Label); | |
| // Print public part of RSA key | |
| if ((privateKey.PublicKey != null) && (privateKey.PublicKey is RsaKeyParameters)) | |
| { | |
| RsaKeyParameters rsa = privateKey.PublicKey as RsaKeyParameters; | |
| Console.WriteLine(" RSA exponent: " + ConvertUtils.BytesToHexString(rsa.Exponent.ToByteArrayUnsigned())); | |
| Console.WriteLine(" RSA public modulus: " + ConvertUtils.BytesToHexString(rsa.Modulus.ToByteArrayUnsigned())); | |
| } | |
| j++; | |
| } | |
| // Print certificates | |
| int k = 1; | |
| foreach (Certificate certificate in certificates) | |
| { | |
| X509Certificate2 x509Cert = CertUtils.ToDotNetObject(certificate.Data); | |
| Console.WriteLine(); | |
| Console.WriteLine("Certificate no." + k); | |
| Console.WriteLine(" ID (CKA_ID): " + certificate.Id); | |
| Console.WriteLine(" Label (CKA_LABEL): " + certificate.Label); | |
| Console.WriteLine(" Serial number: " + x509Cert.SerialNumber); | |
| Console.WriteLine(" Subject DN: " + x509Cert.Subject); | |
| Console.WriteLine(" Issuer DN: " + x509Cert.Issuer); | |
| Console.WriteLine(" Not before: " + x509Cert.NotBefore); | |
| Console.WriteLine(" Not after: " + x509Cert.NotAfter); | |
| // Print certified public RSA key | |
| if ((certificate.PublicKey != null) && (certificate.PublicKey is RsaKeyParameters)) | |
| { | |
| RsaKeyParameters rsa = certificate.PublicKey as RsaKeyParameters; | |
| Console.WriteLine(" RSA exponent: " + ConvertUtils.BytesToHexString(rsa.Exponent.ToByteArrayUnsigned())); | |
| Console.WriteLine(" RSA public modulus: " + ConvertUtils.BytesToHexString(rsa.Modulus.ToByteArrayUnsigned())); | |
| } | |
| k++; | |
| } | |
| } | |
| } | |
| private void OldTry() | |
| { | |
| X509Certificate2 certificate = null; | |
| var store = new X509Store(StoreLocation.CurrentUser); | |
| store.Open(OpenFlags.ReadOnly); | |
| var certificates = store.Certificates.Find(X509FindType.FindBySerialNumber, "00D61D016B3381AC0A", false); | |
| Console.WriteLine("Certificates count: {0}", certificates.Count); | |
| certificate = certificates[0]; | |
| var data = certificate.Export(X509ContentType.SerializedCert, "78963"); | |
| RSACryptoServiceProvider csp = null; | |
| if (certificate.HasPrivateKey) | |
| csp = (RSACryptoServiceProvider)certificate.PrivateKey; | |
| using (Pkcs11 pkcs = new Pkcs11("bit4ipki_x64.dll", false)) | |
| { | |
| // Find first slot with token present | |
| Slot slot = GetUsableSlot(pkcs); | |
| // Open RW session | |
| using (Session session = slot.OpenSession(false)) | |
| { | |
| // Login as normal user | |
| session.Login(CKU.CKU_USER, Settings.Default.PinCode); | |
| session.Logout(); | |
| } | |
| } | |
| X509Certificate2 cert = null; | |
| using (Pkcs11RsaSignature pkcs11RsaSignature = | |
| new Pkcs11RsaSignature("bit4ipki_x64.dll", "1020000000050957", null, "78963", | |
| "6961E845-B33C-4E56-9504-FAF59D24D516", null, Net.Pkcs11Interop.PDF.HashAlgorithm.SHA1)) | |
| { | |
| byte[] signingCertificate = pkcs11RsaSignature.GetSigningCertificate(); | |
| cert = CertUtils.ToDotNetObject(signingCertificate); | |
| } | |
| } | |
| private static Slot GetUsableSlot(Pkcs11 pkcs11) | |
| { | |
| // Get list of available slots with token present | |
| List<Slot> slots = pkcs11.GetSlotList(true); | |
| // First slot with token present is OK... | |
| Slot matchingSlot = slots[0]; | |
| // ...unless there are matching criteria specified in Settings class | |
| if (Settings.TokenSerial != null || Settings.TokenLabel != null) | |
| { | |
| matchingSlot = null; | |
| foreach (Slot slot in slots) | |
| { | |
| TokenInfo tokenInfo = null; | |
| try | |
| { | |
| tokenInfo = slot.GetTokenInfo(); | |
| } | |
| catch (Pkcs11Exception ex) | |
| { | |
| if (ex.RV != CKR.CKR_TOKEN_NOT_RECOGNIZED && ex.RV != CKR.CKR_TOKEN_NOT_PRESENT) | |
| throw; | |
| } | |
| if (tokenInfo == null) | |
| continue; | |
| if (!string.IsNullOrEmpty(Settings.TokenSerial)) | |
| if (0 != string.Compare(Settings.TokenSerial, tokenInfo.SerialNumber, StringComparison.Ordinal)) | |
| continue; | |
| if (!string.IsNullOrEmpty(Settings.TokenLabel)) | |
| if (0 != string.Compare(Settings.TokenLabel, tokenInfo.Label, StringComparison.Ordinal)) | |
| continue; | |
| matchingSlot = slot; | |
| break; | |
| } | |
| } | |
| return matchingSlot; | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment