CAPICOM and X509 - x509certificate2

I have a web application form. The aim is to create a xml of data from web form and sign it with the user usb certificate.
I am using CAPICOM.store to successfully open all user certificate. When I click on one that I want I exported it. After that I am importing selected certificate in X509Cetificate2 to sign xml. But in my code I am getting error on line
signedXml.ComputeSignature() and message is 'Signing key is not loaded.' Please any help or suggestion to fix this.
Function SignXML(uppXML As String) As String
Dim bResult As Boolean = False
Dim pCertContext As IntPtr = IntPtr.Zero
Dim doc As XmlDocument = Nothing
Dim signedXml As SignedXml = Nothing
Dim reference As Reference = Nothing
Dim trns As XmlDsigC14NTransform = Nothing
Dim env As XmlDsigEnvelopedSignatureTransform = Nothing
Dim keyInfo As KeyInfo = Nothing
Dim xmlDigitalSignature As XmlElement = Nothing
Dim hideFiledCapicom As String = Replace(txtCapicom.Text, " ", "+")
Dim certificate As New X509Certificate2(Convert.FromBase64String(hideFiledCapicom))
Dim key As AsymmetricAlgorithm = certificate.PrivateKey
doc = New XmlDocument
doc.PreserveWhitespace = True
doc.LoadXml(uppXML)
signedXml = New SignedXml(doc)
signedXml.SigningKey = key
reference = New Reference
reference.Uri = ""
trns = New XmlDsigC14NTransform
reference.AddTransform(trns)
env = New XmlDsigEnvelopedSignatureTransform
reference.AddTransform(env)
signedXml.AddReference(reference)
keyInfo = New KeyInfo()
keyInfo.AddClause(New KeyInfoX509Data(certificate))
signedXml.KeyInfo = keyInfo
signedXml.ComputeSignature()
xmlDigitalSignature = signedXml.GetXml()
doc.DocumentElement.AppendChild(doc.ImportNode(xmlDigitalSignature, True))
If TypeOf doc.FirstChild Is XmlDeclaration Then
doc.RemoveChild(doc.FirstChild)
End If
uppXML = doc.OuterXml
Return uppXML
End Function

I found solution for this.
In JavaScript where I use CAPICOM to choose and export certificate I am also getting and the private key from certificate and putting it in hidden fields.
var privateKey = certificates.Item(1).PrivateKey.KeySpec
var exportKey = document.getElementById("<%=hideFieldKey.ClientID%>");
exportKey = privateKey
document.getElementById('HiddenKey').value = exportKey;
In my vb code I use CspParameters() to get private key and RSACryptoServiceProvider() to proceed further for signing xml document.

Related

Getting Type mismatch: 'b64_hmac_sha1' error on Classic ASP OAuth 2.0 call for access token

I'm trying to get an OAuth 2.0 access_token and am getting an error message on the include page. here's the function that is giving the message.
Private Function Get_Signature()
Dim strBaseSignature : strBaseSignature = _
m_strMethod & "&" & _
Utils.URLEncode(m_strEndPoint) & "&" & _
Utils.URLEncode(m_strParameters)
Dim strSecret : strSecret = _
m_strConsumerSecret & "&" & _
m_strTokenSecret
Get_Signature = b64_hmac_sha1(strSecret, strBaseSignature)
End Function
End Class
The check page that is calling this function is as follows:
cso = LCase(Request.Form("user"))
pwd = LCase(Request.Form("password"))
appID = 82
Response.Cookies("username") = cso
Response.Cookies("password") = pwd
Response.Cookies("ValidUser") = Validated
Dim objOAuth : Set objOAuth = New cLibOAuth
objOAuth.ConsumerKey = "{client_id}"
objOAuth.ConsumerSecret = "{secretkey}"
objOAuth.EndPoint = "https://login.company.com/as/token.oauth2"
objOAuth.RequestMethod = OAUTH_REQUEST_METHOD_POST
objOAuth.TimeoutURL = "authenticate.asp"
objOAuth.Parameters.Add "username", Request.Cookies("username")
objOAuth.Parameters.Add "password", Request.Cookies("password")
objOAuth.Parameters.Add "oauth_callback", "callback.asp"
objOAuth.Send()
Dim strResponse : strResponse = _
objOAuth.Get_ResponseValue(access_token)
I'm getting an error message of Type mismatch: 'b64_hmac_sha1' in this section:
Get_Signature = b64_hmac_sha1(strSecret, strBaseSignature)
It should have ran the objOAuth call and added the request paramaters and went to the callback.asp page but it's failing on the paramaters.
I'm new to Oauth and rusty on classic asp. It's a project I have got to get finished so any help is appreciated.

Google Closure Compile REST Api suddenly Throws Error 405 "Method not allowed"

I've been using Closure as part of y application to compress Javascript for a while now, but just started getting an error 405 - Method not allowed
My code as below was working for a couple of years, but has now stopped.
NOTE: this is not called frequently, just when ever any changes are detected in the Javascript files in my application.
I get no further error information from the Closure app than this.
Obviously this code performs a POST operation. If I use the form found here https://closure-compiler.appspot.com/home, it works, but if I either browser to the URL or use my code I get Error 405, it's almost as if my code is trying a GET method... but it's not...
Any ideas?
Public Class Closure
Property OriginalCode As String
Property CompiledCode As String
Property Errors As ArrayList
Property Warnings As ArrayList
Property Statistics As Dictionary(Of String, Object)
Public Sub New(Input As String, Optional CompliationLevel As String = "SIMPLE_OPTIMIZATIONS")
Dim _HttpWebRequest As HttpWebRequest
Dim _Result As StringBuilder
Dim ClosureWebServiceURL As String = "http://closure-compiler.appspot.com/compile?"
Dim ClosureWebServicePOSTData As String = "output_format=json&output_info=compiled_code" &
"&output_info=warnings" &
"&output_info=errors" &
"&output_info=statistics" &
"&compilation_level=" & CompliationLevel & "" &
"&warning_level=default" &
"&js_code={0}"
'// Create the POST data
Dim Data = String.Format(ClosureWebServicePOSTData, HttpUtility.UrlEncode(Input))
_Result = New StringBuilder
_HttpWebRequest = DirectCast(WebRequest.Create(ClosureWebServiceURL), HttpWebRequest)
_HttpWebRequest.Method = "POST"
_HttpWebRequest.ContentType = "application/x-www-form-urlencoded"
'//Set the content length to the length of the data. This might need to change if you're using characters that take more than 256 bytes
_HttpWebRequest.ContentLength = Data.Length
'//Write the request stream
Using SW As New StreamWriter(_HttpWebRequest.GetRequestStream())
SW.Write(Data)
End Using
Try
Dim response As WebResponse = _HttpWebRequest.GetResponse()
Using responseStream As Stream = response.GetResponseStream
Dim encoding As Encoding = System.Text.Encoding.GetEncoding("utf-8")
Using readStream As New StreamReader(responseStream, encoding)
Dim read(256) As Char
Dim count As Integer = readStream.Read(read, 0, 256)
While count > 0
Dim str As New String(read, 0, count)
_Result.Append(str)
count = readStream.Read(read, 0, 256)
End While
End Using
End Using
Dim js As New JavaScriptSerializer
js.MaxJsonLength = Int32.MaxValue
Dim d As Dictionary(Of String, Object) = js.Deserialize(Of Dictionary(Of String, Object))(_Result.ToString())
Me.CompiledCode = d.NullKey("compiledCode")
Me.Warnings = TryCast(d.NullKey("warnings"), ArrayList)
Me.Errors = TryCast(d.NullKey("errors"), ArrayList)
Me.Statistics = TryCast(d.NullKey("statistics"), Dictionary(Of String, Object))
Catch ex As Exception
Me.CompiledCode = ""
If Me.Errors Is Nothing Then
Dim er As New List(Of String)
er.Add(ex.ToString())
Me.Errors = New ArrayList(er)
Else
Me.Errors.Add(ex.ToString())
End If
End Try
Me.OriginalCode = Input
End Sub
End Class
Closure REST api is redirecting to https, you may want to try to POST to "https://closure-compiler.appspot.com/compile" directly in order to avoid redirection.

Encryption in Web service not giving the same result compared to the one on the main project

I am trying to pass an encrypted string from my web service to my main project but when I am trying to perform decryption, it returns "Invalid length for a Base-64 char array or string." because the result of the encryption in my main project is not the same with the one in my web service but I'm just using the same encryption.
Sample ("SessionExpired"):
Web Service encryption ->
tDaxnTVCaLOxWSIYVZLO5lxJm%2bX1Vg1CcEPXFb1DBLk%3d
Main Project Encryption ->
tDaxnTVCaLOxWSIYVZLO5lxJm%252bX1Vg1CcEPXFb1DBLk%253d
Encryption and Decryption Code
Public Function password_encrypt(clearText As String) As String
Dim EncryptionKey As String = "MAKV2SPBNI99212"
Dim clearBytes As Byte() = Encoding.Unicode.GetBytes(clearText)
Using encryptor As Aes = Aes.Create()
Dim pdb As New Rfc2898DeriveBytes(EncryptionKey, New Byte() {&H49, &H76, &H61, &H6E, &H20, &H4D,
&H65, &H64, &H76, &H65, &H64, &H65,
&H76})
encryptor.Key = pdb.GetBytes(32)
encryptor.IV = pdb.GetBytes(16)
Using ms As New MemoryStream()
Using cs As New CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write)
cs.Write(clearBytes, 0, clearBytes.Length)
cs.Close()
End Using
clearText = Convert.ToBase64String(ms.ToArray())
End Using
End Using
Return clearText
End Function
Public Function password_decrypt(cipherText As String) As String
If cipherText <> Nothing Then
Dim EncryptionKey As String = "MAKV2SPBNI99212"
Dim cipherBytes As Byte() = Convert.FromBase64String(cipherText)
Using encryptor As Aes = Aes.Create()
Dim pdb As New Rfc2898DeriveBytes(EncryptionKey, New Byte() {&H49, &H76, &H61, &H6E, &H20, &H4D,
&H65, &H64, &H76, &H65, &H64, &H65,
&H76})
encryptor.Key = pdb.GetBytes(32)
encryptor.IV = pdb.GetBytes(16)
Using ms As New MemoryStream()
Using cs As New CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write)
cs.Write(cipherBytes, 0, cipherBytes.Length)
cs.Close()
End Using
cipherText = Encoding.Unicode.GetString(ms.ToArray())
End Using
End Using
End If
Return cipherText
End Function

Ruby on Rails OpenSSL HMAC Equivalent to VB.NET/C# HMAC

I'm running into a problem where I cannot get the Hash value from VB.Net to match the hash value in Ruby on Rails. I'm wondering if this is almost the equivalent way to do it. The problem relies in my VB code.
Here's an example of the code:
Ruby
key = 'key'
data = 'The quick brown fox jumps over the lazy dog'
digest = OpenSSL::Digest::MD5.new
hmac = OpenSSL::HMAC.hexdigest(digest, key, data)
VB.Net
Dim key As String = "key"
Dim value As String = ""
Function getMD5Hash(ByVal input As String) As String
Dim md5Hasher As New HMACMD5()
Dim data As Byte() = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input))
Dim sBuilder As New StringBuilder()
Dim i As Integer
For i = 0 To data.Length - 1
sBuilder.Append(data(i).ToString("x2"))
Next i
Return sBuilder.ToString()
End Function
Private Sub Test()
Dim data As String = "The quick brown fox jumps over the lazy dog"
value = getMD5Hash(key + data)
testing.Text = value
End Sub
Protected Sub btnSubmit_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles testBtn.Click
Test()
End Sub

Why does my stored procedure always think there is a value?

I have an ASP.NET 2010 app hitting a SQL 2005 db. I am attempting to build a stored proc dynamically, depending on the values selected on a search screen. I have done this many times in previosu versions of .net & sql with no problem. However, now, my IF statement always always acts as though no data was passed in. I have debugged the app and am sure that data is being set. I should note that when I run the procedure directly, with or without data, the correct data is returned.
Here is the rather simple stored proc..
ALTER PROCEDURE get_cases_by_search_criteria
#vin as varchar(30) = null
AS
declare #sqlstr varchar(1000)
set #sqlstr = 'SELECT
[Case].CaseID,
[Case].VIN,
[Case].Make,
[Case].Model,
[Case].VehicleYear,
if #vin is not null and #vin <> ''
set #sqlstr = #sqlstr + ' and ' + ('[Case].VIN = ''' + convert(varchar,#vin) + '''')
exec(#sqlstr)
RETURN
And here is the code that calls the stored proc...
Public Function GetCases(ByVal oSearchCriteria As SearchCriteria) As List(Of BE.Case)
Dim lstCase As New List(Of BE.Case)
Dim oCase As BE.Case
Dim oProviderFactory As New ProviderFactory
Dim oConnection As DbConnection
Dim oReader As System.Data.IDataReader
Dim oFactory As DbProviderFactory
Dim oCmd As DbCommand
Dim param1 As System.Data.Common.DbParameter
Try
'call my class to get an instance of the DBProviderFactory class
oFactory = oProviderFactory.GetFactory
'call another class of mine. pass in the DBProviderFactory class which will create a non-provider-specific connection object
oConnection = oProviderFactory.GetProviderConnection(oFactory)
'non-specific create command
oCmd = oConnection.CreateCommand
'non-specific parameter
If oSearchCriteria.VIN.Length = 0 Then
param1 = oFactory.CreateParameter()
param1.ParameterName = "#vin"
param1.DbType = DbType.String
param1.Value = DBNull.Value
oCmd.Parameters.Add(param1)
Else
param1 = oFactory.CreateParameter()
param1.ParameterName = "#vin"
param1.DbType = DbType.String
param1.Value = oSearchCriteria.VIN
oCmd.Parameters.Add(param1)
End If
oCmd.CommandType = CommandType.StoredProcedure
oCmd.CommandText = "get_cases_by_search_criteria"
Using (oConnection)
oConnection.Open()
oReader = oCmd.ExecuteReader()
While oReader.Read
oCase = New BE.Case
'Case
If oReader("CaseID") IsNot System.DBNull.Value Then oCase.CaseID = oReader("CaseID")
If oReader("Make") IsNot System.DBNull.Value Then oCase.Make = oReader("Make")
If oReader("Model") IsNot System.DBNull.Value Then oCase.Model = oReader("Model")
If oReader("VehicleYear") IsNot System.DBNull.Value Then oCase.VehicleYear = oReader("VehicleYear")
If oReader("VIN") IsNot System.DBNull.Value Then oCase.VIN = oReader("VIN")
lstCase.Add(oCase)
End While
oConnection.Close()
End Using
Catch ex As Exception
Throw ex
End Try
Return lstCase
End Function

Resources