I got problem when try to generate keys using ASP.NET (.NET 4) for RSA, the RSACryptoServiceProvider throws invalid flags specified exception.
[CryptographicException: Invalid flags specified.
]
System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) +33
System.Security.Cryptography.Utils._GenerateKey(SafeProvHandle hProv, Int32 algid, CspProviderFlags flags, Int32 keySize, SafeKeyHandle& hKey) +0
System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle& safeKeyHandle) +9719339
System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair() +89
System.Security.Cryptography.RSACryptoServiceProvider.ExportParameters(Boolean includePrivateParameters) +38
System.Security.Cryptography.RSA.ToXmlString(Boolean includePrivateParameters) +45
I initialize the RSA using this code:
var _cpsParameter = new CspParameters();
_cpsParameter.Flags = CspProviderFlags.UseMachineKeyStore;
var rsaProvider = new RSACryptoServiceProvider(bitStrength, _cpsParameter);
string publicAndPrivateKeys = rsaProvider.ToXmlString(true);
string justPublicKey = rsaProvider.ToXmlString(false);
Any idea how to solve this ?
One possible explanation might be that you already have a non-exportable key in the key-container with the name "" (in that case .NET will just use the existing key instead of overwriting it with a new key).
Try this code instead and see if that makes a difference:
var cspParameters = new CspParameters();
cspParameters.Flags = CspProviderFlags.UseMachineKeyStore;
cspParameters.KeyContainerName = Guid.NewGuid().ToString();
var rsaProvider = new RSACryptoServiceProvider(bitStrength, cspParameters);
string publicAndPrivateKeys = rsaProvider.ToXmlString(true);
string justPublicKey = rsaProvider.ToXmlString(false);
Related
I get an error when trying to sign data with .NET Core using CMS with certificate
X509Store st = new X509Store(StoreName.My, StoreLocation.LocalMachine);
st.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certSelected = st.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
st.Close();
var signerCert = certSelected[0];
ContentInfo contentInfo = new ContentInfo(msg);
SignedCms signedCms = new SignedCms(contentInfo, true);
CmsSigner cmsSigner = new CmsSigner(signerCert);
cmsSigner.IncludeOption = X509IncludeOption.EndCertOnly;
signedCms.ComputeSignature(cmsSigner, false);
I get the error below when computing the signature
Error occurred during a cryptographic operation.
at Internal.Cryptography.Pal.Windows.HelpersWindows.GetProvParameters(SafeProvOrNCryptKeyHandle handle)
at Internal.Cryptography.Pal.Windows.PkcsPalWindows.GetPrivateKey[T](X509Certificate2 certificate, Boolean silent, Boolean preferNCrypt)
at Internal.Cryptography.Pal.Windows.PkcsPalWindows.GetPrivateKeyForSigning[T](X509Certificate2 certificate, Boolean silent)
at System.Security.Cryptography.Pkcs.CmsSignature.RSAPkcs1CmsSignature.Sign(ReadOnlySpan`1 dataHash, HashAlgorithmName hashAlgorithmName, X509Certificate2 certificate, AsymmetricAlgorithm key, Boolean silent, String& signatureAlgorithm, Byte[]& signatureValue)
at System.Security.Cryptography.Pkcs.CmsSignature.Sign(ReadOnlySpan`1 dataHash, HashAlgorithmName hashAlgorithmName, X509Certificate2 certificate, AsymmetricAlgorithm key, Boolean silent, String& oid, ReadOnlyMemory`1& signatureValue)
at System.Security.Cryptography.Pkcs.CmsSigner.Sign(ReadOnlyMemory`1 data, String contentTypeOid, Boolean silent, X509Certificate2Collection& chainCerts)
at System.Security.Cryptography.Pkcs.SignedCms.ComputeSignature(CmsSigner signer, Boolean silent)
The same code works in .NET Framework 4.5.2
Any idea what could be wrong here and how to fix it in .NET Core?
I've managed to get this working by:
defining the Oid in ContentInfo
defining the Oid in CmsSigner
using a different constructor for CmsSigner
New code below with the changes
X509Store st = new X509Store(StoreName.My, StoreLocation.LocalMachine);
st.Open(OpenFlags.ReadOnly);
X509Certificate2Collection certSelected = st.Certificates.Find(X509FindType.FindByThumbprint, thumbprint, false);
st.Close();
var signerCert = certSelected[0];
Oid dstOid = new Oid("1.2.840.113549.1.7.2"); // PKCS#7
ContentInfo contentInfo = new ContentInfo(dstOid, msg);
SignedCms signedCms = new SignedCms(contentInfo, true);
CmsSigner signerWindowStore = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, signerCert, signerCert.GetRSAPrivateKey());
signerWindowStore.DigestAlgorithm = new Oid("1.3.14.3.2.26"); // SHA1
signerWindowStore.IncludeOption = X509IncludeOption.EndCertOnly;
signedCms.ComputeSignature(signerWindowStore, false);
Our production application recently started getting the elusive "There is an error in XML document (1, 6110)." Up until a few days ago everything was working as expected. I don't have access to the server logs to see if any unexpected updates were performed, but I can't think of a reason why it has been working fine and now doesn't. Just for reference, this is happening on load of a Data set from a web service. The culprit column datatype is Geography and I can confirm the correct version of Microsoft.SqlServer.Types is present on Client and Server sides. "is not allowed here." is what I can't figure out?!?!
Below is the complete error message:
System.InvalidOperationException was caught
HResult=-2146233079
Message=There is an error in XML document (1, 6110).
Source=System.Xml
StackTrace:
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall)
at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters)
at DataFutures.DatabaseRoutines.DFIWebTier.DFIWebTier.Web_ReturnLoadedDataSet(String TableName_String, Boolean UseStoredProcedure_Boolean, String SQLCommandOrStoredProcedureName_String, String ParameterName_String, String SelectValue_String, String ParameterName2_String, String SelectValue2_String, SQLParameter_Class[] SQLParameter_SQLParameter_Class, String ConnectionString_String, String Database_String) in C:\DevApps\TeamServer\Generic Routines\DLLs\DatabaseRoutines\Web References\DFIWebTier\Reference.vb:line 240
at DataFutures.DatabaseRoutines.DF_DataBaseClass.Database_Return_LoadedDataSet(String DataTable_String, Boolean UseStoredProcedure_Boolean, String SQLCommandOrStoredProcedureName_String, String ParameterName_String, String SelectValue_String, String ParameterName2_String, String SelectValue2_String, String ConnectionString_String, SqlTransaction SQL_SqlTransaction, List`1 SQLParameter_SQLParameter_Class, String Database_String) in C:\DevApps\TeamServer\Generic Routines\DLLs\DatabaseRoutines\Classes\DF_DatabaseClass.vb:line 1442
at DataFutures.DatabaseRoutines.DF_DataBaseClass.get_ExecuteReturnLoadedDataSet() in C:\DevApps\TeamServer\Generic Routines\DLLs\DatabaseRoutines\Classes\DF_DatabaseClass.vb:line 736
at DataFutures.Maintenance_Health.FacilityIC_Form.LoadTabPage_GeneralTab() in C:\DevApps\TeamServer\CareScope\Modules\Maintenance\Facility\FacilityIC_Form.vb:line 3905
InnerException: System.InvalidOperationException
HResult=-2146233079
Message=Type 'Microsoft.SqlServer.Types.SqlGeography, Microsoft.SqlServer.Types, Version=12.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91' is not allowed here. See https://go.microsoft.com/fwlink/?linkid=2132227 for more information.
Source=System.Data
StackTrace:
at System.Data.TypeLimiter.EnsureTypeIsAllowed(Type type, TypeLimiter capturedLimiter)
at System.Data.DataColumn.UpdateColumnType(Type type, StorageType typeCode)
at System.Data.DataColumn.set_DataType(Type value)
at System.Data.XSDSchema.SetProperties(Object instance, XmlAttribute[] attrs)
at System.Data.XSDSchema.HandleElementColumn(XmlSchemaElement elem, DataTable table, Boolean isBase)
at System.Data.XSDSchema.HandleParticle(XmlSchemaParticle pt, DataTable table, ArrayList tableChildren, Boolean isBase)
at System.Data.XSDSchema.HandleComplexType(XmlSchemaComplexType ct, DataTable table, ArrayList tableChildren, Boolean isNillable)
at System.Data.XSDSchema.InstantiateTable(XmlSchemaElement node, XmlSchemaComplexType typeNode, Boolean isRef)
at System.Data.XSDSchema.HandleTable(XmlSchemaElement node)
at System.Data.XSDSchema.HandleDataSet(XmlSchemaElement node, Boolean isNewDataSet)
at System.Data.XSDSchema.LoadSchema(XmlSchemaSet schemaSet, DataSet ds)
at System.Data.DataSet.ReadXSDSchema(XmlReader reader, Boolean denyResolving)
at System.Data.DataSet.ReadXml(XmlReader reader, XmlReadMode mode, Boolean denyResolving)
at System.Data.DataSet.ReadXmlSerializable(XmlReader reader)
at System.Data.DataSet.System.Xml.Serialization.IXmlSerializable.ReadXml(XmlReader reader)
at System.Xml.Serialization.XmlSerializationReader.ReadSerializable(IXmlSerializable serializable, Boolean wrappedAny)
at System.Xml.Serialization.XmlSerializationReader.ReadSerializable(IXmlSerializable serializable)
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderDFIWebTier.Read6_Item()
at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer7.Deserialize(XmlSerializationReader reader)
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events)
InnerException:
The reason is right there in the link. You have to opt-in for serializing types other than the basic ones. You probably have this configured for a previous version of the Spatial types, but when they were updated on the server, the configuration didn't get updated on the client.
Here's an example:
using System.Data.SqlClient;
using Microsoft.SqlServer.Types;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;
using System.Threading.Tasks;
namespace SqlClientTest
{
class Program
{
static void Main(string[] args)
{
var constr = "server=localhost;database=master;integrated security=true;";
using (var con = new SqlConnection(constr))
{
con.Open();
Type[] extraAllowedTypes = new Type[]
{
typeof(SqlGeography)
};
AppDomain.CurrentDomain.SetData("System.Data.DataSetDefaultAllowedTypes", extraAllowedTypes);
var sel = new SqlCommand("select geography::STGeomFromText('LINESTRING(-122.360 47.656, -122.343 47.656 )', 4326) shape", con);
var da = new SqlDataAdapter(sel);
var ds = new DataSet();
da.Fill(ds);
var ms = new MemoryStream();
ds.WriteXml(ms, XmlWriteMode.WriteSchema);
ms.Position = 0;
using (var f = File.OpenWrite("out.xml"))
{
ms.CopyTo(f);
}
ms.Position = 0;
var ds2 = new DataSet();
ds2.ReadXml(ms);
}
}
}
}
I have an ASP.NET 4.5 application with a separate class library for accessing the Google analytics data. Every try to use the common methods (loading the certificat from .p12 file) ends in an "internal error" (the file will be found!) in 3rd line (Dim certificat...)
Dim scopes As String() = New String() {AnalyticsService.Scope.Analytics}
Dim serviceAccountEmail = "info#xxx.biz"
Dim certificate = New X509Certificate2(System.Web.HttpContext.Current.Server.MapPath("Certificates/MyDashboard-b335c24b1a76.p12"), "notasecret", X509KeyStorageFlags.Exportable)
Dim credential = New ServiceAccountCredential(New ServiceAccountCredential.Initializer(serviceAccountEmail) With {.Scopes = scopes}.FromCertificate(certificate))
Dim service = New AnalyticsService(New BaseClientService.Initializer() With { _
.HttpClientInitializer = credential, _
.ApplicationName = "MyDashboard" _
})
Dim MyRequest As DataResource.GaResource.GetRequest = service.Data.Ga.Get("ga:44582845", "2016-01-01", "2016-01-01", "ga:sessions")
MyRequest.MaxResults = 1000
Dim MyResult As GaData = MyRequest.Execute()
[CryptographicException: Interner Fehler.
]
System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr) +41
System.Security.Cryptography.X509Certificates.X509Utils._LoadCertFromFile(String fileName, IntPtr password, UInt32 dwFlags, Boolean persistKeySet, SafeCertContextHandle& pCertCtx) +0
System.Security.Cryptography.X509Certificates.X509Certificate.LoadCertificateFromFile(String fileName, Object password, X509KeyStorageFlags keyStorageFlags) +307
System.Security.Cryptography.X509Certificates.X509Certificate2..ctor(String fileName, String password, X509KeyStorageFlags keyStorageFlags) +92
GoogleAnalyticsClient.Class1..ctor() in P:\Google Analytics\GoogleAnalyticsClient\Class1.vb:59
preisvergleich.Statistik.Page_Load(Object sender, EventArgs e) in \web\Webs\AFFILIATE 2.0\preisvergleich\Statistik.aspx.vb:16
System.EventHandler.Invoke(Object sender, EventArgs e) +0
System.Web.UI.Control.LoadRecursive() +71
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3178
Is there any possibility to access the analytics data without the certificate (I think it was in former times)?
BR Jan
There is a special working progress where we encrypt and decrypt an input.
Suddenly, yesterday, there was an encrypted string we weren't able to decrypt.
It seems my cryptographic knowledge aren't good enough to solve this problem.
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Crypto
{
using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;
public static class Crypto
{
public static void Main()
{
//String NotWorking_dec = "鈦ꧪ㧘聯ꢮ玗硴廜᭮⸂濅�";
String enc ="mIAU::__*?";
//String dec = "砿첩뜞ꦽ嶾蝡泛ɝࠪ塤偏ꍨ";
Console.WriteLine(decrypt(dec));
//writeFile(encrypt(enc));
Console.ReadLine();
}
private static string key = "ZlKMpRwoPLmNXEpCLxEa6g==";
private static string iv = "U5ZB4W4bQqg=";
private static ICryptoTransform enc;
private static ICryptoTransform dec;
static Crypto()
{
RC2 rc = System.Security.Cryptography.RC2.Create();
enc = rc.CreateEncryptor(Convert.FromBase64String(key), Convert.FromBase64String(iv));
dec = rc.CreateDecryptor(Convert.FromBase64String(key), Convert.FromBase64String(iv));
}
public static String encrypt(String value)
{
byte[] input = toBytes(value);
return toString(enc.TransformFinalBlock(input, 0, input.Length));
}
public static String decrypt(String value)
{
byte[] input = toBytes(value);
Console.WriteLine(input.Length);
return toString(dec.TransformFinalBlock(input, 0, input.Length));
}
private static void writeFile(String value)
{
try
{
StreamWriter sw = new StreamWriter("output.tmp", true);
sw.WriteLine(value);
sw.Close();
}
catch (Exception ex) { }
}
private static byte[] toBytes(String value)
{
return Encoding.Unicode.GetBytes(value);
}
private static String toString(byte[] value)
{
return Encoding.Unicode.GetString(value);
}
}
}
This working progress works for months.
You are able to test it with the input
mIAU::__*?
you get
砿첩뜞ꦽ嶾蝡泛ɝࠪ塤偏ꍨ
decrypt it and you get again
mIAU::__*?
But the encrypted String "鈦ꧪ㧘聯ꢮ玗硴廜᭮⸂濅�" throws errors: (Of course we used the same key and iv)
BAD DATA
bei System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
bei System.Security.Cryptography.Utils._DecryptData(SafeKeyHandle hKey, Byte[] data, Int32 ib, Int32 cb, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode PaddingMode, Boolean fDone)
bei System.Security.Cryptography.CryptoAPITransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
bei Crypto.Crypto.decrypt(String value) in c:\Users\Td\Documents\Visual Studio 2013\Projects\Crypto\Crypto\Program.cs:Zeile 56.
bei Crypto.Crypto.Main() in c:\Users\Td\Documents\Visual Studio 2013\Projects\Crypto\Crypto\Program.cs:Zeile 23.
bei System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
bei System.AppDomain.nExecuteAssembly(RuntimeAssembly assembly, String[] args)
bei System.Runtime.Hosting.ManifestRunner.Run(Boolean checkAptModel)
bei System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly()
bei System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext, String[] activationCustomData)
bei System.Runtime.Hosting.ApplicationActivator.CreateInstance(ActivationContext activationContext)
bei System.Activator.CreateInstance(ActivationContext activationContext)
bei Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone()
bei System.Threading.ThreadHelper.ThreadStart_Context(Object state)
bei System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
bei System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
bei System.Threading.ThreadHelper.ThreadStart()
You cannot simply convert random bytes to strings and back. Not all bytes are valid character encodings. You need to apply for instance base 64 encoding to your binary ciphertext if you require text. Otherwise you will loose data, depending on the value of the ciphertext. And the ciphertext will contain random byte values. So it may fail now and then, as you are currently experiencing.
Java silently converts unknown bytes to characters by default, for instance it will create a � character if it cannot convert byte(s) to a character. This is why this particular string fails.
Besides that, Unicode contains a lot of characters that are not easily printable, and even characters that can be created using either two Unicode code points or a single one. So a Unicode string may have multiple possible encodings, so it is doubly unsuitable for conveying binary data.
All in all, text should not be directly used to convey binary data. The data needs to be encoded first.
my code is like the follow:
SqliteConnection db = new SqliteConnection("uri=file:zongheng.db");db.Open();
SqliteCommand cmd = db.CreateCommand();
cmd.CommandText = "update chapters set status = 0 where bookid=" + bookid + " and chapterid = " + reading_chapter + ";";
cmd.ExecuteNonQuery();
cmd.Dispose();
db.Close();
db.Dispose();
db.Open();
cmd = db.CreateCommand();
cmd.CommandText = ("select max(chapterid), status from chapters where status > 0 and bookid = "+bookid +";");
SqliteDataReader dr = cmd.ExecuteReader(); //exception thrown from here
calling stack is like this:
Community.CsharpSqlite.SQLiteClient.SqliteSyntaxException was unhandled
Message=unable to open database file
StackTrace:
at Community.CsharpSqlite.SQLiteClient.SqliteCommand.GetNextStatement(String pzStart, String& pzTail, Vdbe& pStmt)
at Community.CsharpSqlite.SQLiteClient.SqliteCommand.ExecuteReader(CommandBehavior behavior, Boolean want_results, Int32& rows_affected)
at Community.CsharpSqlite.SQLiteClient.SqliteCommand.ExecuteReader(CommandBehavior behavior)
at Community.CsharpSqlite.SQLiteClient.SqliteCommand.ExecuteReader()
at ZonghengReader.Content.OnNavigatedTo(NavigationEventArgs e)
at Microsoft.Phone.Controls.PhoneApplicationPage.InternalOnNavigatedTo(NavigationEventArgs e)
at System.Windows.Navigation.NavigationService.RaiseNavigated(Object content, Uri uri, NavigationMode mode, Boolean isNavigationInitiator, PhoneApplicationPage existingContentPage, PhoneApplicationPage newContentPage)
at System.Windows.Navigation.NavigationService.CompleteNavigation(DependencyObject content, NavigationMode mode)
at System.Windows.Navigation.NavigationService.ContentLoader_BeginLoad_Callback(IAsyncResult result)
at System.Windows.Navigation.PageResourceContentLoader.BeginLoad_OnUIThread(AsyncCallback userCallback, PageResourceContentLoaderAsyncResult result)
at System.Windows.Navigation.PageResourceContentLoader.<>c__DisplayClass4.<BeginLoad>b__0(Object args)
at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at System.Delegate.DynamicInvokeOne(Object[] args)
at System.MulticastDelegate.DynamicInvokeImpl(Object[] args)
at System.Delegate.DynamicInvoke(Object[] args)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority)
at System.Windows.Threading.Dispatcher.OnInvoke(Object context)
at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args)
at System.Windows.Hosting.DelegateWrapper.InternalInvoke(Object[] args)
at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam[] pParams, ScriptParam& pResult)
how can i do different queries within the same connection? any advice? or any documentation? any advice would be highly appreciated.
I don't know if this question is answered yet but... in your code sample you dispose of the object:
...
db.Dispose();
db.Open();
...
I honestly think that's your problem in the current context. just remove the Dispose() call on the database connection object and I think you should be fine. Once you are really done with the object you can Dispose() it.