I am trying to figure out how I would create a composite KEY with the geode native client APIs. Does someone have a simple example of how I would do this in .NET? For example, say my data class is:
MyDataObject
string field1;
string field2;
string field3;
I want a composite key on field1 and field2. What would this look like in C# .NET?
I would make a string of field1.field2 as the key. Although a key can also be the whole object. But I use strings for keys and build composite keys out of strings as said.
So your region type would be:
IRegion<String, MyDataObject>
Related
We are experiencing some issues with EF6 and Always encrypted feature.
I believe we need to set up something into DBContext, in order to instruct how to encrypt or decrypt columns, but I couldn't find a way to do this.
We already have an ADO access layer, and it works perfectly with encrypted fields. We would rather use EF instead of ADO.
Symptoms are:
With EF, We are able to query the data. And decryption process works fine.
Insertion process throws error below:
Operand type clash: varchar is incompatible with varchar(8000) encrypted with (encryption_type = 'DETERMINISTIC', encryption_algorithm_name = 'AEAD_AES_256_CBC_HMAC_SHA_256', column_encryption_key_name = 'CEK_Auto1', column_encryption_key_database_name = 'Development_v2_qa') collation_name = 'SQL_Latin1_General_CP1_CI_AS'**
Query with where clause, using an encrypted field, throws same error.
Technologies used:
EF6 with Poco entities.
AzureKeyVault for storing encryp/decryp masterkey.
Using SSL Certidicate to authenticate against KeyVault
Connection string contains "Column Encryption Setting=enabled;"
AzureSqlServer
FWK4.6
ADO
We have some code which works fine with ADO. It works fine with every SqlConnection
// Instantiate our custom AKV column master key provider.
// It uses the GetToken function as the callback function to authenticate to AKV
SqlColumnEncryptionAzureKeyVaultProvider akvprov = new SqlColumnEncryptionAzureKeyVaultProvider();
akvprov.KeyVaultClient = SecureConfigurationManager.KeyVaultClient;
// Register the instance of custom provider to SqlConnection
Dictionary<string, SqlColumnEncryptionKeyStoreProvider> providers = new Dictionary<string, SqlColumnEncryptionKeyStoreProvider>();
// "SqlColumnEncryptionAzureKeyVaultProvider.ProviderName" is the name of the provider. It must match the string we used when we created the column master key
providers.Add(SqlColumnEncryptionAzureKeyVaultProvider.ProviderName, akvprov);
SqlConnection.RegisterColumnEncryptionKeyStoreProviders(providers);
Yep, I just found the same problem, needed to add
[Column(TypeName = "varchar(max)")]
in the POCO type before the field for it to work.
Be nice if the error was a bit clearer (and nicer still if NVARCHAR did actually work)
I'm working through the same issue. The problem is with the datatype mapping from C# to the database. Not all the lengths matter at all for always encrypted and varchars with Entity Framework, only varchar(max) or varchar(8000). I have all the entity framework working with azure key vault for all the datatypes, same as you. This link below shows how to do the insert with inline SQL. I've only worked with entity framework and hope I never have to work in inline sql, even though I might have to, if I can't find a way to shrink down the database storage overhead needed for encryption, or look to something like Stretch Db, also another feature in SQL Server 2016. Thanks Jakub Szymaszek and Microsoft.
I have conceded and made all of my data types varchar(max) and it works just fine. So string = varchar(max). The weird thing is that there is not 8000 characters in the encryption, but there is probably 8000 allocated.
"something1" becomes this after encryption and insert:
0x0190F9D80C3F70890FB154F2123459506AD5BDA165333710D161ED80E42FCAFA882C66FF5B68E412B5F9EE11A9F308201D0AE2BD4032151398171FDBE2F3AEA20D
Interesting thing about varchar(max) is that supposidly there is a link to a table or somewhere else the data is stored, beside the table it is inserted into, so varchar(max) may only take the amount shown. (I'm a dev)
The dataType for my column and stored procedure variables:
[testVarChar] varchar COLLATE Latin1_General_BIN2 ENCRYPTED WITH (COLUMN_ENCRYPTION_KEY = [CEK_Auto1], ENCRYPTION_TYPE = Randomized, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256') NOT NULL,
The data type of the parameter targeting the SSN column is set to an ANSI (non-Unicode) string, which maps to the char/varchar SQL Server data type. If the type of the parameter was set to a Unicode string (String), which maps to nchar/nvarchar, the query would fail, as Always Encrypted does not support conversions from encrypted nchar/nvarchar values to encrypted char/varchar values. See SQL Server Data Type Mappings for information about the data type mappings.
https://learn.microsoft.com/en-us/sql/relational-databases/security/encryption/develop-using-always-encrypted-with-net-framework-data-provider
I am pulling in some XML data using XmlProvider, and I will be accessing it from C#. As you can't use type provided fields directly from C#, I need create record out of them. I can do this by hand but I believe this should be possible to automate using reflection. If I create record types with the same names and types as the fields in the type provider, I should be able to use something like FSharpValue.MakeRecord(typeof<MyType>,values) where values is an array of objects.
What I don't know is how to get the array of values out of the type provider, and how to handle nested records, for instance:
type Address =
{
Address1 : string
City : string
State : string
}
type Client =
{
Id : int
FullName : string
Address : Address
}
In this case Client contains one Address. Will I need to walk the tree and use MakeRecord on the leaves and work my way up?
If you're willing to hand code the types, why do you need the type provider in the first place?
If you're doing some additional logic on F# side, you'll have no choice but to create the records manually anyway. And if you're not doing anything, you can just use the .NET out of the box serializer (or another library) to create them from xml.
I have a serialized EC public key - its CKA_EC_PARAMS and CKA_EC_POINT. There's a matching private key on my token. Is there any way to find it?
With an RSA key, I can do a FindObjects with CKA_KEY_TYPE=CKK_PRIVATE_KEY and CKA_MODULUS=. Is there a way to do the same thing with EC keys? According to the PKCS#11 spec, CKA_EC_POINT isn't an attribute for EC Private Keys.
I have a token with support for EC at hand, and it seems that the only way to associate the private and public key will be through the CKA_ID value. No attribute available to test directly the key value.
Actually, even in the case of RSA that's the basic standard method to associate a private and a public key, they ought to be created with identical CKA_ID (that's what the Netscape browser originally did, and everyone copied on that).
They are even some buggy pkcs#11 implementations that won't allow you to read the CKA_MODULUS value of a RSA private key (this is definitevely a bug since the spec explicitly says this value ought to always be public, but it's just one of many bad things frequently happpening with pkcs#11). With them, CKA_ID is the only way even for RSA.
I'm using a javascript plugin called jSignature to give my MVC4 application delivery signature capture functionality. jSignature outputs the signature info in a data:image/png;base64,iVBORw0KG... string format that looks to be around 32,000 characters long. I created a property in my model called DeliverySignature as a string and am able to save and retrieve the signature data but when I pull it back in from the database it's only about 5,000 characters long. What data type do I need to be using in my model's definition and in the action method (it's being passed in to a controller to save to the db) so that it preservers the complete string length? Thank you.
I would store it in varchar(max) column.
You can keep model property type of string as strings do not have a limited length.
Good day.
I need to teach Windows CryptoAPI to encrypt the message with private (not public) part of the key, and decrypt with public. This is necessary to give users information, that they can read, but can't change.
How it works now:
I get the context
CryptAcquireContext(#Prov, PAnsiChar(containerName), nil, PROV_RSA_FULL, 0)
generate a key pair
CryptGenKey(Prov, CALG_RSA_KEYX, CRYPT_EXPORTABLE, #key)
Encrypt (and the problem is here. "key" - a keypair, and the function uses its public part);
CryptEncrypt(key, 0, true, 0, #res[1], #strLen, buffSize)
Decrypt (the same problem here, it uses the private part of the key)
CryptDecrypt(key, 0, true, 0, #res[1], #buffSize)
Thank you for your attention / help.
Update
Yes, I could use a digital signature and other metods...
The problem is that I need to encrypt one database field and make sure that no one but me can change it. It will be possible to read this field only with the help of my program (till someone decompiles it and get public key). This could be done with symmetrical key and digital signatures, but then i will need to create another field and store another key and so on...
I do hope that we can somehow teach WIN API to do as I want. I know that i can do so with RSA, and I hope that somehow WinAPI supports this feature.
Strictly speaking, when "signing" a message:
the person with the private key decrypts the hash with their private key.
they then send that "decrypted" hash along with the message.
the receiver then encrypts the signature with the public key
If the "encrypted" hash matches the hash of the original message, you know the message has not been altered, and was sent by the person with the private key. The following pseudo-code represents the signing algorithm:
//Person with private key generating message and signature
originalHash = GenerateHashOfMessage(message);
signature = RsaDecrypt(originalHash, privateKey);
//Receiver validating signed message
hash = GenerateHashOfMessage(message);
originalHash = RsaEncrypt(signature, publicKey);
messageValid = (hash == originalHash);
This same mechanism can be used to accomplish what you want. Except you don't care about hashes, you just want to encrypt some (small) amount of data:
//Person with private key
cipherText = RsaDecrypt(plainText, privateKey);
//Person with public key
plainText = RsaEncrypt(cipherText, publicKey);
i'll leave the CryptoAPI calls as an excercise - since i'm still trying to figure out Microsoft's Crypto API.
Encrypting data with the private key and decrypting it with the public key isn't supported because anyone with the "published" public key could decrypt it. What's the value in encrypting it then?
If you want to verify that data hasn't been changed, you will want to sign the data instead. Signing encrypts a hash of the data with the private key. Look at the signing functions.
You may be able to trick out the signing functions to do what you want. I've done this with other implementations, but I haven't tried with the Microsoft CryptoAPI.
Also, note that with RSA encryption, the plain text message cannot be longer than the key. So, if you are using a 2048 bit key, you can only encrypt a message body of up to 256 bytes (minus a few for overhead).
Consider using asymmetric encryption just to pass a symmetric key, and use the symmetric key to encrypt and decrypt any size data.
Update
You may be able to use the CryptSignHash() function for this. Normally, this is used to "sign" a hash, but you can put any data you want into the hash:
Set the hash value in the hash object by using the HP_HASHVAL value of
the dwParam parameter in CryptSetHashParam.
You might be limited to so many bytes if the input is expected to be a SHA1 hash value.
Alternatively, you may wish to consider using OpenSSL. If I recall correctly, it's pretty straight forward to use its RSA signing functions to encrypt with the private key.
Also, I accomplished the same thing using the old (freeware) version of SecureBlackbox. You may be able to find the old free version, but it's not Unicode friendly, so you'll have some conversion to do if you're using a new Delphi. I've done this in the past also, so it's not too difficult.
You may also consider trying out the current SecureBlackbox and purchase it if it works for you.
Otherwise, as you stated, sign it to detect tampering, and encrypt it with a symmetric key that only the program knows in order to obfuscate it.
If they crack your code, anything's fair game anyway.