Need to change encryption algorithm to AES-256 - mimekit

I wrote a test program to read a users cert from the cert store, and encrypt some text. However, I realize that the encryption algorithm used is 3DES. I need to change this to AES-256. I read a similar post on here, but for me, i think my situation is slightly different...So, I'll get straight to the point.
Using the suggested method:
var recipient = new CmsRecipient("MyCert.cer");
recipient.EncryptionAlgorithms = new EncryptionAlgorithm[] {
EncryptionAlgorithm.Aes256
};
var CmsCollection = new CmsRecipientCollection();
CmsCollection.Add(recipient);
// Followed by calling ApplicationPkcs7Mime.Encrypt(CmsCollection, p7m);
I'm able to change the encryption algorithm... However my key-encryption algorithm, is not the same if I were to do it using my original method of simply using the MailboxAddress to encrypt. E.g.:
MimeMessage mm = new MimeMessage();
mm.From.Add(new MailboxAddress(from));
mm.To.Add(new MailboxAddress(to));
ApplicationPkcs7Mime.Encrypt(mm.To.Mailboxes, p7m);
Using the CmsRecipientCollection method, this is the result of my pkcs7m file:
You can see, that the key-encryption algorithm has changed to rsaOAEP,and the email client that I'm sending this message to cannot recognize this algorithm.
Whereas, using the Mailbox method to encrypt:
I'm stuck with 3DES, while the key encryption algorithm is correct...
So I guess, end of day, what I'm asking is, is there a way to get both key-encryption algorithm to be rsaEncryption, and the block cipher to be AES-256?
I saw an method UpdateSecureMimeCapabilities in the API reference, would this be able to do the job?
Also, I guess a more fundamental question is, why would the key-encryption algorithm change if both methods are essentially using the same cert?
Thanks!
Update:
So I created a custom class to override the GetPreferredEncryptionAlgorithm function, however it's still falling back to 3DES.
public class CustomWindowsSecureMimeContext : WindowsSecureMimeContext
{
public CustomWindowsSecureMimeContext () : base ()
{
}
protected override EncryptionAlgorithm GetPreferredEncryptionAlgorithm(CmsRecipientCollection recipients)
{
return EncryptionAlgorithm.Aes256;
}
}
Did I override it correctly?

The UpdateSecureMimeCapabilities method isn't going to help in your case. It's not used when enveloping data, it's only used when decoding signed messages (it's a way for you to update your database of S/MIME capabilities of the email clients used by your correspondents).
There is no way to specify a key encryption algorithm in MimeKit because I haven't been able to figure out how to specify it in BouncyCastle (used by any of the BouncyCastleSecureMimeContext subclasses) nor in Microsoft's CMS API (used by WindowsSecureMimeContext). It seems to make that decision on its own.
Whichever SecureMimeContext class you use, you can override the GetPreferredEncryptionAlgorithm() method(s) to provide your own algorithm for choosing an encryption algorithm that would be suitable to use to encrypt the message to all of the specified recipients -or- you could override the GetCmsRecipient() method which takes a MailboxAddress and creates a new CmsRecipient for that recipient.
The other option is to use the MimeKit.Cryptography.CmsRecipient[Collection] API's in order to set the CmsRecipient.EncryptionAlgorithms property which represents the encryption algorithms supported by that recipient's email client. If you set an array of EncryptionAlgorithms that includes Aes256 for each recipient, then that algorithm will be chosen.

Related

Changing a Private Ethereum Key into a PEM or HMAC algorithm in NodeJS

I have a private key, which is:
0x66228b427f07b168c7cb1380aa5554403b9e24bf935a9364c89711a306a23ddb
NOTE: The Original Key was the Public Key when the question was posted:
0x6a2043113D5640F9F50dC593D0DcD8CC1c970EB1
I generated it randomly for this question, so don't worry that it's public on the Internet.
I want to use it as the encryption scheme for a JWT token, using the ES256 algorithm.
To get it into my library, I have to have it in one these formats.
secretOrPrivateKey is a string, buffer, or object containing either the secret for HMAC algorithms or the PEM encoded private key for RSA and ECDSA. In case of a private key with passphrase an object { key, passphrase } can be used (based on crypto documentation), in this case be sure you pass the algorithm option.
Is there any easy way to move the hex value to one of these formats? Or, will this not work because I'm not understanding the difference between an Ethereum Private key and a ES256?
Etherium keys are actually ES256K and not ES256 so in this case it might not be possible.
If you need to turn the key in PEM in NodeJS there is a library called key-encoder for this specific purpose. Which can be accomplished with the following code.
var KeyEncoder = require('key-encoder');
console.log(KeyEncoder.default);
let keyEncoder = new KeyEncoder.default('secp256k1')
var pemPrivateKey = keyEncoder.encodePrivate('0x66228b427f07b168c7cb1380aa5554403b9e24bf935a9364c89711a306a23ddb', 'raw', 'pem')
console.log(pemPrivateKey);

Nonce reuse for different recipients?

I'm generating a new random symmetric key and want to pass that to multiple people using crypto_box_easy.
Is it okay to reuse the same (random) nonce for the same message and same sender but for different recipients? Can the same nonce be used for a symmetric encryption with the random key and crypto_secretbox_easy?
As the nonce has to be served along with the encrypted message it can't be hidden anyway, but is reuse across multiple different recipients a problem? If they provide a badly generated public key, can that weaken encryption in a way that other peoples' secret keys could be extracted?
Thanks a lot.
A nonce can be reused as long as a (key, nonce) tuple is not reused.
You're right that reusing a nonce with the same key would result in a catastrophic loss of privacy with a stream cipher like XSalsa20.
The thing is, crypto_box_easy uses the recipients public key to generate a shared secret that is then used with a nonce.
Thus even with a static nonce, the (nonce, key) pair for each recipient will be different.
Although, it's not acceptable to use the same (nonce, key) pair twice, you can use the same nonce for each recipient, but only once.
It's acceptable to use the same nonce once for each recipient using the crypto_box_easy construct ONCE.
It even states this in the libsodium documentation:
The nonce doesn't have to be confidential, but it should be used with just one invocation of crypto_box_easy() for a particular pair of public and secret keys.
i.e. for one message per recipient.

How can I encode URL parameters?

I used this method in class library and calling the method from controller. But the value i passed is not encoding. I cant trace the reason behind it.
Class Library
using System.Web;
public static class CommonLogic
{
public static string UrlEncode(string value)
{
return HttpUtility.UrlEncode(value);
}
}
Controller
var test = CommonLogic.UrlEncode("2")
test value is "2" and it not encoded.
Update:
I just realized the reason from comments below. What i really need is not encoding but encryption and decryption. I don't want the Url parameters to be exposed as plain text, instead i want that to be encrypted value and later in controller i will decrypt it again before processing that value. Any Ideas on this?
"2" doesn't need to be UrlEncoded. It's not a reserved symbol in Urls. Try testing a string such as "<".
The purpose of the UrlEncode method is to convert a string to a format that can be used in an URL. "2" is already can be used in an URL so this is a null-conversion it will result in the same value of "2".
Section 2 of RFC 3986 outlines what characters have to be encoded to become part of an URL.
Character "2" is part of the "unreserved" set as defined in RFC3986 https://www.rfc-editor.org/rfc/rfc3986#section-2.3
The "unreserved" do not need to be percent-encoded.
Regarding your comment about exposing it in the URL: encoding is not encryption. If you don't want to expose the integer user id in the URL you may need to have another unique identifier for the user that is OK to expose. For example, a random string that is unique in the user table (similar to how say youtube.com identifies videos) or a GUID.
Example of how to do simple symmetric encryption in C# using RijndaelManaged:
Simple insecure two-way data "obfuscation"?
Make sure you keep the encryption key secret.

Design patterns: How can concrete implementations select behaviours at run time?

I'm new to the terminology, so please correct me if I've phrased any part of my question wrong.
Here's the example that I'm thinking of:
A file synchronization program that lets you pair 2 folders together, and specify options such as mirror the two folders, only copy contents one way, etc.
How would I specify at run time how each of these concrete implementations copy the files (eg, different types of encryption).
Here is what I'd somewhat like to accomplish:
http://i.imgur.com/fkVN9.png
Do I have to make concrete implementations for each? ie MirrorAes, MirrorBlowfish, OnewayAes, etc? Is there a better alternative?
Thanks
The way that your diagram is showing it, the way you encrypt appears to be dependent on the way that you do synchronization. I doubt that this is the case (although I may be wrong).
If the way you sync is truly independent of the way you encrypt, switch from inheritance to composition. Make FolderPair an object that has a SyncStrategy and an EncryptionStrategy, like this:
class FolderPair {
URI a, b;
private final SyncStrategy syncStrategy;
private final EncryptionStrategy cryptStrategy;
public FolderPair(
URI a
, URI b
, SyncStrategy syncStrategy
, EncryptionStrategy cryptStrategy) {
...
}
public void sync() {
syncStrategy.synchronize(a, b, cryptStrategy);
}
}
interface SyncStrategy {
void synchronize(URI a, URI b, EncryptionStrategy cryptStrategy);
}
interface EncryptionStrategy {
byte[] encrypt(byte[] data);
}
Now you can configure your FolderPair objects with instances of SyncStrategy and EncryptionStrategy, mixing and matching them without creating combinatorial explosion:
FolderPair p1 = new FolderPair(aUri, bUri, new OneWyaSync(), new AesCrypt());
This design features two applications of the Strategy Pattern - one for the synchronization behavior, and the other one for the encryption.
You've got orthogonal concerns - the sync type and the encryption. One way to approach this is the Strategy Pattern, where your concrete implementations of the synchronization classes aggregate an encryption class, and the synchronizers interact with an encryption interface, allowing "mix and match" encryption and synchronization without having a multiplier effect on the number of classes you write.
You mean, you need an encryption strategy?
Use an abstract factory together with a set of strategies for encryption. In case you have multiple options, use a builder.
Let's say, you have a SHA1Encryption and a DESEncryption. Both implement an interface, say, GeneralEncryptionStrategy, and you have an EncryptionFactory, which takes a string (either "sha1" or "des") as an argument and creates an instance of the corresponding class.

I'm using Wincrypt for Diffie-Hellman-- can I export the shared secret in plain text?

OK-- thanks to Mike, I was able to get Wincrypt to generate a Diffie-Hellman keypair. I figured out out to export the public key, and how to import the other party's public key. According to the docs, upon import of the other party's public key, the shared secret has been computed. Great.
I now need to get ahold of that shared secret, but I don't think its possible. Simply calling CryptExportKey with a type of PLAINTEXTKEYBLOB fails unless I call CryptSetKeyParam to change the algorithm id from CALG_AGREEDKEY_ANY to something... else. But I don't want something else, I want the shared secret. The API, however, seems designed to discourage this.
Any ideas out there? I should note that the problem here is that I'm only writing one side of an implementation of WiFi Protected Setup. So the protocol is defined for me, and the other party is not giving me HCRYPTKEYs.
This looks like what you need...
from: http://msdn.microsoft.com/en-us/library/aa381969(VS.85).aspx
To import a Diffie-Hellman public key and calculate the secret session key
Call the CryptAcquireContext function to get a handle to the Microsoft Diffie-Hellman Cryptographic Provider.
Create a Diffie-Hellman key by calling the CryptGenKey function to create a new key, or by calling the CryptGetUserKey function to retrieve an existing key.
To import the Diffie-Hellman public key into the CSP, call the CryptImportKey function, passing a pointer to the public key BLOB in the pbData parameter, the length of the BLOB in the dwDataLen parameter, and the handle to the Diffie-Hellman key in the hPubKey parameter. This causes the calculation, (Y^X) mod P, to be performed, thus creating the shared, secret key and completing the key exchange. This function call returns a handle to the new, secret, session key in the hKey parameter.
At this point, the imported Diffie-Hellman is of type CALG_AGREEDKEY_ANY. Before the key can be used, it must be converted into a session key type. This is accomplished by calling the CryptSetKeyParam function with dwParam set to KP_ALGID and with pbData set to a pointer to a ALG_ID value that represents a session key, such as CALG_RC4. The key must be converted before using the shared key in the CryptEncrypt or CryptDecrypt function. Calls made to either of these functions prior to converting the key type will fail.
The secret session key is now ready to be used for encryption or decryption.
When the key is no longer needed, destroy the key handle by calling the CryptDestroyKey function.