Consume web service in C# with digital sign the request - c#

I need to consume a web service (SOAP) in C# with digital sign the request. But everytime I got the 400 bad request with message that "The Login failed because of an exception: javax.security.auth.login.LoginException: CWWSS6810E: The runtime can not identify the key corresponding to the identifier [Xqgkv4YNXYZgUmgtTX+s+ffshm4=].</" Here is my code:
public BSCACustomWcfServiceClient(string clientCertificatePath, string pfxCertificatePath)
{
clientCertificate = new X509Certificate2(clientCertificatePath);
pfxCertificate = new X509Certificate2(pfxCertificatePath, "BlueShieldCa2022!");
}
public string GetClientList()
{
System.ServiceModel.Channels.AsymmetricSecurityBindingElement asbe = new AsymmetricSecurityBindingElement();
asbe.MessageSecurityVersion = MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10;
asbe.InitiatorTokenParameters = new System.ServiceModel.Security.Tokens.X509SecurityTokenParameters { InclusionMode = SecurityTokenInclusionMode.Never };
asbe.RecipientTokenParameters = new System.ServiceModel.Security.Tokens.X509SecurityTokenParameters { InclusionMode = SecurityTokenInclusionMode.Never };
asbe.MessageProtectionOrder = System.ServiceModel.Security.MessageProtectionOrder.EncryptBeforeSign;
asbe.SecurityHeaderLayout = SecurityHeaderLayout.Strict;
asbe.IncludeTimestamp = true;
asbe.DefaultAlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.Basic128;
CustomBinding myBinding = new CustomBinding();
myBinding.Elements.Add(asbe);
myBinding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap12, Encoding.UTF8));
HttpsTransportBindingElement httpsBindingElement = new HttpsTransportBindingElement();
httpsBindingElement.RequireClientCertificate = true;
myBinding.Elements.Add(httpsBindingElement);
Uri httpUri = new Uri("uri");
EndpointAddress endPoint = new EndpointAddress(httpUri);
ServiceReference1.ReportsClient cliente = new ServiceReference1.ReportsClient(myBinding, endPoint);
cliente.Endpoint.Contract.ProtectionLevel = ProtectionLevel.None;
cliente.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None;
cliente.ClientCredentials.ServiceCertificate.DefaultCertificate = clientCertificate;
cliente.ClientCredentials.ClientCertificate.Certificate = pfxCertificate;
cliente.Open();
string ReportName = "MCP Client Listing";
string ReportType = "TAB";
string TimeStamp = DateTime.Now.ToString("yyyy-MM-ddThh:mm:ss.fffZ");
string SenderId = "CMSZZ00573";
string SenderName = "MY TEST ORGANIZATION";
string OrganizationId = "9999";
string ReceiverId = "DHCS CMS NET";
string Payload = "MCP Client Listing";
byte[] Payload1;
string ErrorCode;
string ErrorMessage;
var res = cliente.ClientListEnvelope(ref ReportName, ref ReportType, ref TimeStamp, ref SenderId, SenderName, ref OrganizationId, ref ReceiverId, Payload, out Payload1, out ErrorCode, out ErrorMessage);
return null;
}
Can anyone help to resolve the issue?

Related

Netsuite Token Based Authentication, Invalid Login Attempt

I am trying a NetSuite integration (SOAP), with Token-Based Authentication, and always get "Invalid Login attempt", all the credentials are right, when I am trying a get request to:
"https://accountid.suitetalk.api.netsuite.com/services/NetSuitePort_2017_1", I receive :
This is my c# code :
public static void Get()
{
var nonce = ComputeNonce();
var timeStamp = ComputeTimestamp();
var customer = new Customer();
var tokenPassport = new TokenPassport()
{
account = Account,
consumerKey = ConsumerKey,
token = TokenId,
nonce = nonce,
timestamp = timeStamp,
signature = new TokenPassportSignature()
{
Value = GetEncodedSignature(nonce, timeStamp),
algorithm = "HMAC_SHA256"
}
};
var netsuiteclient = new NetSuitePortTypeClient();
var res = netsuiteclient.getAsync(null, tokenPassport, null, null, null, new RecordRef()).Result;
}
public static string GetEncodedSignature(string nonce, long timeStamp)
{
string baseString = $"{Account}&{ConsumerKey}&{TokenId}&{nonce}&{timeStamp}";
string secretKey = $"{ConsumerSecret}&{TokenSecret}";
HMACSHA256 hashObject = new HMACSHA256(Encoding.UTF8.GetBytes(secretKey));
byte[] signature = hashObject.ComputeHash(Encoding.UTF8.GetBytes(baseString));
return Convert.ToBase64String(signature);
}
private static string ComputeNonce()
{
RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider();
byte[] data = new byte[20];
rng.GetBytes(data);
int value = Math.Abs(BitConverter.ToInt32(data, 0));
return value.ToString();
}
private static long ComputeTimestamp()
{
return ((long)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds);
}
Could somebody help, Thank you !

Client certificate not working in xamarin.android

I'm trying to establish mtls connection using https://github.com/chkr1011/MQTTnet library in my xamarin.android project. During this process I encountered with such an exception in Init method on calling conResult.Wait(TimeSpan.FromSeconds(60));
{MQTTnet.Exceptions.MqttCommunicationException: Authentication failed, see inner exception. ---> System.Security.Authentication.AuthenticationException: Authentication failed, see inner exception. ---> System.Security.Cryptography.CryptographicException: Caught…}
{System.Security.Cryptography.CryptographicException: Caught unhandled exception in MonoBtlsSslCtx.ProcessHandshake. ---> System.NullReferenceException: Object reference not set to an instance of an object.
at Mono.Btls.MonoBtlsSsl.SetPrivateKey (Mono.Btls.…}
This is my code:
public void Init()
{
ILoadCertificate certificateService = DependencyService.Get<ILoadCertificate>();
var cert = certificateService.LoadPemCertificate("certificate", "private_key");
Console.WriteLine(cert.GetRSAPrivateKey());
string clientId = Guid.NewGuid().ToString();
string mqttURI = "";
int mqttPort = 8883;
var factory = new MqttFactory();
var mqttClient = factory.CreateMqttClient();
bool disableServerValidation = true;
var tlsParameters = new MqttClientOptionsBuilderTlsParameters
{
UseTls = true,
Certificates = new[] { new X509Certificate(cert.Export(X509ContentType.Cert)) },
IgnoreCertificateChainErrors = disableServerValidation,
AllowUntrustedCertificates = disableServerValidation,
SslProtocol = System.Security.Authentication.SslProtocols.Tls12,
CertificateValidationHandler = (o) =>
{
return true;
},
};
var connectOptions = new MqttClientOptionsBuilder()
.WithProtocolVersion(MQTTnet.Formatter.MqttProtocolVersion.V311)
.WithClientId(clientId)
.WithTcpServer(mqttURI, mqttPort)
.WithCommunicationTimeout(new TimeSpan(0, 2, 30))
.WithCleanSession()
.WithTls(tlsParameters)
.Build();
var conResult = mqttClient.ConnectAsync(connectOptions);
conResult.ContinueWith(r =>
{
Console.WriteLine(r.Result.ResultCode);
Console.WriteLine(r.Exception.StackTrace);
});
conResult.Wait(TimeSpan.FromSeconds(60));
var t = mqttClient.PublishAsync("events/test", "test");
t.ContinueWith(r =>
{
Console.WriteLine(r.Result.PacketIdentifier);
Console.WriteLine(r.Exception.StackTrace);
});
t.Wait();
}
//This methods is used to construct certificate:
public X509Certificate2 GetCertificate(string pemCert, string pemKey)
{
string fileNameCert = Path.Combine(Environment
.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), pemCert);
var pem = File.ReadAllText(fileNameCert);
string fileNameKey = Path.Combine(Environment
.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), pemKey);
var key = File.ReadAllText(fileNameKey);
var keyPair = (AsymmetricCipherKeyPair)new PemReader(new StringReader(key))
.ReadObject();
var cert = (Org.BouncyCastle.X509.X509Certificate)new PemReader(new
StringReader(pem)).ReadObject();
var builder = new Pkcs12StoreBuilder();
builder.SetUseDerEncoding(true);
var store = builder.Build();
var certEntry = new X509CertificateEntry(cert);
store.SetCertificateEntry("", certEntry);
store.SetKeyEntry("", new AsymmetricKeyEntry(keyPair.Private), new[] { certEntry });
byte[] data;
using (var ms = new MemoryStream())
{
store.Save(ms, Array.Empty<char>(), new SecureRandom());
data = ms.ToArray();
}
return new X509Certificate2(data);
}
public byte[] GetBytesFromPEM(string pemString, string type)
{
string header; string footer;
switch (type)
{
case "cert":
header = "-----BEGIN CERTIFICATE-----";
footer = "-----END CERTIFICATE-----";
break;
case "key":
header = "-----BEGIN RSA PRIVATE KEY-----";
footer = "-----END RSA PRIVATE KEY-----";
break;
default:
return null;
}
int start = pemString.IndexOf(header) + header.Length;
int end = pemString.IndexOf(footer, start) - start;
return Convert.FromBase64String(pemString.Substring(start, end));
}
I have several options:
Maybe there is some issue with constructing certificate in GetCertificate method;
There is issue with MqttNet library itself. I suspect that the library does not work with certificates in xamarin.android, because i found such topics: https://github.com/xamarin/xamarin-android/issues/4481, https://github.com/chkr1011/MQTTnet/issues/883.
I tried to construct certificate this way, but xamarin does not support rsa.ImportRSAPrivateKey. I have got: System.PlatformNotSupportedException: Operation is not supported on this platform.
string fileNameCert = Path.Combine(Environment
.GetFolderPath(Environment
.SpecialFolder.LocalApplicationData), certificatePath);
using var publicKey = new X509Certificate2(fileNameCert);
string fileNameKey = Path.Combine(Environment
.GetFolderPath(Environment
.SpecialFolder.LocalApplicationData), privateKeyPath);
using var rsa = RSA.Create();
byte[] keyBuffer =
GetBytesFromPEM(File.ReadAllText(fileNameKey), "key");
int o;
rsa.ImportRSAPrivateKey(keyBuffer, out o);
var keyPair = publicKey.CopyWithPrivateKey(rsa);
return new X509Certificate2(keyPair.Export(X509ContentType.Pkcs12));

I can't get a soap message in C#

I'm getting an error:
A security error was encountered when verifying the message
Https is expected when I somehow overcome this error. But I have to use Http.
EndpointAddress address2 = new EndpointAddress("http://xx.xx.xxxx/ws/test?wsdl");
FactoryWebServiceClient client = new FactoryWebServiceClient();
client.Endpoint.Address = address2;
if (client.ClientCredentials != null)
{
client.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential("username","password");
client.ClientCredentials.UserName.UserName = "username";
client.ClientCredentials.UserName.Password = "password";
}
XmlDocument doc = new XmlDocument();
doc.Load("C:\\...\\test.xml");
byte[] bytes = Encoding.Default.GetBytes(doc.OuterXml);
var request2 = new factoryWSUpdateData
{
BeanXml = bytes,
Period = 1,
InputType = "xml",
OutputType = "json2",
CodeTemplate = 1
};
var result = client.create(request2);

Bad Request with no reason

I am attempting to upgrade to newest APNS connectivity functionality but when I submit a request I get a http 400 bad request result with no reason. What am I missing / doing wrong?
Method for sending below:
public async void SendAsync(string deviceToken, string p8privateKey, string p8privateKeyId, string teamId)
{
var path = $"/3/device/{deviceToken}";
var obj = new
{
aps = new
{
alert = "test00001"
}
};
var json = Newtonsoft.Json.JsonConvert.SerializeObject(obj);
var request = new HttpRequestMessage(HttpMethod.Post, new Uri("https://api.development.push.apple.com:443" + path))
{
Version = new Version(2, 0)
};
string jwToken = CreateJwtToken(p8privateKey, p8privateKeyId, teamId);
request.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("bearer", jwToken);
request.Headers.TryAddWithoutValidation(":method", "POST");
request.Headers.TryAddWithoutValidation(":path", path);
request.Headers.Add("apns-topic", "com.the-app");
request.Content = new StringContent(json);
string sReq = JsonConvert.SerializeObject(request);
string jsonContent = request.Content.ReadAsStringAsync().Result;
WinHttpHandler handler = new WinHttpHandler();
HttpClient http = new HttpClient(handler);
var t = await http.SendAsync(request);
}
Here are the other used methods:
private static string CreateJwtToken(string p8privateKeyId, string p8privateKey, string teamId)
{
var header = JsonHelper.Serialize(new { alg = "ES256", kid = p8privateKeyId });
var payload = JsonHelper.Serialize(new { iss = teamId, iat = ToEpoch(DateTime.UtcNow) });
var key = CngKey.Import(Convert.FromBase64String(p8privateKey), CngKeyBlobFormat.Pkcs8PrivateBlob);
using (var dsa = new ECDsaCng(key))
{
dsa.HashAlgorithm = CngAlgorithm.Sha256;
var headerBase64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(header));
var payloadBasae64 = Convert.ToBase64String(Encoding.UTF8.GetBytes(payload));
var unsignedJwtData = $"{headerBase64}.{payloadBasae64}";
var signature = dsa.SignData(Encoding.UTF8.GetBytes(unsignedJwtData));
return $"{unsignedJwtData}.{Convert.ToBase64String(signature)}";
}
}
private static int ToEpoch(DateTime time)
{
var span = DateTime.UtcNow - new DateTime(1970, 1, 1);
return Convert.ToInt32(span.TotalSeconds);
}
I have limited to the payload to what I think is the bear minimum requirements. I am new to jwt/http2 and APNS.
I could very well be missing something simple.

Getting parameter_rejected error in quickbook online integration

I have done this code:
static void Main (string[] args)
{
Console.WriteLine("Authenticating..");
string consumerkey = "L0ORES0pf0uEody1YDI3sTkTpyBGaDVVnVRBb1krprkrghPWLQ";
string consumerSecret = "NAONcYrwGgpkFCJN2BgXZHjG8YLqn1JWMEPDXIMg";
string REQUEST_TOKEN_URL = "https://oauth.intuit.com/oauth/v1/get_request_token";
string ACCESS_TOKEN_URL = "https://oauth.intuit.com/oauth/v1/get_access_token";
string OauthLink = "https://developer.intuit.com/v2/OAuth2Playground/RedirectUrl";
var consumerContext = new OAuthConsumerContext
{
ConsumerKey = consumerkey,
ConsumerSecret = consumerSecret,
SignatureMethod = SignatureMethod.HmacSha1
};
IOAuthSession AuthSession = new OAuthSession(consumerContext,REQUEST_TOKEN_URL, OauthLink, ACCESS_TOKEN_URL);
IToken requestToken = AuthSession.GetRequestToken();
}
And I am getting error : An unhandled exception of type 'DevDefined.OAuth.Framework.OAuthException' occurred in DevDefined.OAuth.dll Additional information: parameter_rejected
I have attached screenshot of my error.
What is quickbook online Request token URL and Access token URL for OAuth 2.0?
Oauth2.0 //Refresh and Get New Access Token through WebClient and build ServiceContext for CRUD operations
Access Token will expire in every 60 minutes
string URI = "https://oauth.platform.intuit.com/oauth2/v1/tokens/bearer";
string myParameters = "grant_type=refresh_token&refresh_token=L0115-----------------------------------"; // Put Refresh Token
WebClient wc = new WebClient();
wc.Headers[HttpRequestHeader.ContentType] = "application/x-www-form-urlencoded";
wc.Headers[HttpRequestHeader.Accept] = "application/json";
wc.Headers[HttpRequestHeader.Authorization] = "Basic UT------------------------------hcW5SV---------------------Qg=="; // Add Auth Token
string HtmlResult = wc.UploadString(URI, myParameters);
wc.Dispose();
var jobject = JsonConvert.DeserializeObject<Test>(HtmlResult);
string accessToken = jobject.access_token;
string relmid = "123412341234123421341234"; // Relmid
OAuth2RequestValidator oauthValidator = new OAuth2RequestValidator(accessToken);
ServiceContext serviceContext = new ServiceContext(relmid, IntuitServicesType.QBO, oauthValidator);
serviceContext.IppConfiguration.BaseUrl.Qbo = "https://sandbox-quickbooks.api.intuit.com/";
//serviceContext.IppConfiguration.BaseUrl.Qbo = "https://quickbooks.api.intuit.com/";//prod
serviceContext.IppConfiguration.MinorVersion.Qbo = "23";
CustomerCRUD.CustomerAddTestUsingoAuth(serviceContext);
CustomerCRUD.CustomerFindAllTestUsingoAuth(serviceContext);

Categories

Resources