Generate certificate with custom encoding algorythm - encryption

MakeCert.exe certificate generation utility (https://msdn.microsoft.com/en-us/library/bfsktky3(VS.100).aspx) has -a (algorithm) parameter using for specifying the signature algorithm. Algorithm must be md5, sha1 (the default), sha256, sha384, or sha512.
I need to use russian hash algorythm standard - ГОСТ Р 34.11-94. Is it possible to do this? Or maybe should I use another parameter? Please advise.

You can use flag "eku" and specify oid. In you case oid is "1.2.643.2.2.9"

Related

Where does Linux openssl AES save the IV [duplicate]

I've generated a random 256 bit symmetric key, in a file, to use for encrypting some data using the OpenSSL command line which I need to decrypt later programmatically using the OpenSSL library. I'm not having success, and I think the problem might be in the initialization vector I'm using (or not using).
I encrypt the data using this command:
/usr/bin/openssl enc -aes-256-cbc -salt -in input_filename -out output_filename -pass file:keyfile
I'm using the following call to initialize the decrypting of the data:
EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, keyfile.data(), nullptr))
keyfile is a vector<unsigned char> that holds the 32 bytes of the key. My question is regarding that last parameter. It's supposed to be an initialization vector to the cipher algorithm. I didn't specify an IV when encrypting, so some default must have been used.
Does passing nullptr for that parameter mean "use the default"? Is the default null, and nothing is added to the first cipher block?
I should mention that I'm able to decrypt from the command line without supplying an IV.
What is the default IV when encrypting with EVP_aes_256_cbc() [sic] cipher...
Does passing nullptr for that parameter mean "use the default"? Is the default null, and nothing is added to the first cipher block?
There is none. You have to supply it. For completeness, the IV should be non-predictable.
Non-Predictable is slightly different than both Unique and Random. For example, SSLv3 used to use the last block of ciphertext for the next block's IV. It was Unique, but it was neither Random nor Non-Predictable, and it made SSLv3 vulnerable to chosen plaintext attacks.
Other libraries do clever things like provide a null vector (a string of 0's). Their attackers thank them for it. Also see Why is using a Non-Random IV with CBC Mode a vulnerability? on Stack Overflow and Is AES in CBC mode secure if a known and/or fixed IV is used? on Crypto.SE.
/usr/bin/openssl enc -aes-256-cbc...
I should mention that I'm able to decrypt from the command line without supplying an IV.
OpenSSL uses an internal mashup/key derivation function which takes the password, and derives a key and iv. Its called EVP_BytesToKey, and you can read about it in the man pages. The man pages also say:
If the total key and IV length is less than the digest length and MD5 is used then the derivation algorithm is compatible with PKCS#5 v1.5 otherwise a non standard extension is used to derive the extra data.
There are plenty of examples of EVP_BytesToKey once you know what to look for. Openssl password to key is one in C. How to decrypt file in Java encrypted with openssl command using AES in one in Java.
EVP_DecryptInit_ex(ctx, EVP_aes_256_cbc(), nullptr, keyfile.data(), nullptr))
I didn't specify an IV when encrypting, so some default must have been used.
Check your return values. A call should have failed somewhere along the path. Maybe not at EVP_DecryptInit_ex, but surely before EVP_DecryptFinal.
If its not failing, then please file a bug report.
EVP_DecryptInit_ex is an interface to the AES decryption primitive. That is just one piece of what you need to decrypt the OpenSSL encryption format. The OpenSSL encryption format is not well documented, but you can work it backwards from the code and some of the docs. The key and IV computation is explained in the EVP_BytesToKey documentation:
The key and IV is derived by concatenating D_1, D_2, etc until enough
data is available for the key and IV. D_i is defined as:
D_i = HASH^count(D_(i-1) || data || salt)
where || denotes concatentaion, D_0 is empty, HASH is the digest
algorithm in use, HASH^1(data) is simply HASH(data), HASH^2(data) is
HASH(HASH(data)) and so on.
The initial bytes are used for the key and the subsequent bytes for the
IV.
"HASH" here is MD5. In practice, this means you compute hashes like this:
Hash0 = ''
Hash1 = MD5(Hash0 + Password + Salt)
Hash2 = MD5(Hash1 + Password + Salt)
Hash3 = MD5(Hash2 + Password + Salt)
...
Then you pull of the bytes you need for the key, and then pull the bytes you need for the IV. For AES-128 that means Hash1 is the key and Hash2 is the IV. For AES-256, the key is Hash1+Hash2 (concatenated, not added) and Hash3 is the IV.
You need to strip off the leading Salted___ header, then use the salt to compute the key and IV. Then you'll have the pieces to feed into EVP_DecryptInit_ex.
Since you're doing this in C++, though, you can probably just dig through the enc code and reuse it (after verifying its license is compatible with your use).
Note that the OpenSSL IV is randomly generated, since it's the output of a hashing process involving a random salt. The security of the first block doesn't depend on the IV being random per se; it just requires that a particular IV+Key pair never be repeated. The OpenSSL process ensures that as long as the random salt is never repeated.
It is possible that using MD5 this way entangles the key and IV in a way that leaks information, but I've never seen an analysis that claims that. If you have to use the OpenSSL format, I wouldn't have any hesitations over its IV generation. The big problems with the OpenSSL format is that it's fast to brute force (4 rounds of MD5 is not enough stretching) and it lacks any authentication.

How does CryptContext hashing know what secret to use?

I have the following code snippet:
from passlib.context import CryptContext
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
pwd_context.hash(password)
Which is described here.
What i don't understand is, how can this be secure if it returns the same hashed password all the time without considering another secret_key for example to hash the password value?
Your assumption that it returns the same hashed password all the time without considering another "secret" (well, it's not really secret) is wrong; you'll see this if you run pwd_context.hash multiple times:
>>> from passlib.context import CryptContext
>>>
>>> pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
>>> pwd_context.hash("test")
'$2b$12$0qdOrAMoK7dgySjmNbyRpOggbk.IM2vffMh8rFoITorRKabyFiElC'
>>> pwd_context.hash("test")
'$2b$12$gqaNzwTmjAQbGW/08zs4guq1xWD/g7JkWtKqE2BWo6nU1TyP37Feq'
These two hashes are, as you can see, not the same - even when given the same password. So what's actually going on?
When you don't give hash an explicit salt (the secret "key" you're talking about) one will be generated for you by passlib. It's worth pointing out that hashing is NOT the same as encryption, so there is no key to talk about. Instead you'll see salt mentioned, which is a clear text value that is used to make sure that the same password hashed twice will give different results (since you're effectively hashing salt + password instead).
So why do we get two different values? The salt is the first 22 characters of the actual bcrypt value. The fields are separated by $ - 2b means bcrypt, 12 means 12 rounds, and the next string is the actual resulting value stored for the password (salt+resulting bcrypt hash). The first 22 characters of this string is the hash.
You can see this if you give bcrypt a salt instead of letting it generate one (we'll ignore a possible warning about small padding here, but to show the concept):
>>> pwd_context.hash("test", salt="a"*22)
'$2b$12$aaaaaaaaaaaaaaaaaaaaaOm/4kNFO.mb908CDiMw1TgDxyZeDSwum'
^-------------------^
If we explicitly give the same hash, the result should be the same (and is how you can verify the password later):
>>> pwd_context.hash("test", salt="a"*22)
'$2b$12$aaaaaaaaaaaaaaaaaaaaaOm/4kNFO.mb908CDiMw1TgDxyZeDSwum'
>>> pwd_context.hash("test", salt="a"*22)
'$2b$12$aaaaaaaaaaaaaaaaaaaaaOm/4kNFO.mb908CDiMw1TgDxyZeDSwum'
This same is the case for the previous hashes:
>>> pwd_context.hash("test")
'$2b$12$gqaNzwTmjAQbGW/08zs4guq1xWD/g7JkWtKqE2BWo6nU1TyP37Feq'
^-------------------^
This is the actual generated salt, which is then used together with test to create the actual hash:
>>> pwd_context.hash("test")
'$2b$12$gqaNzwTmjAQbGW/08zs4guq1xWD/g7JkWtKqE2BWo6nU1TyP37Feq'
^------------------------------^
So why do we use this salt when it's clearly visible to everyone? It makes it impossible to just scan through the a list of hashes for known hashes - since test in your list will have a different values than test in the list you're comparing it to (because of different salts), you'll have to actually test the guessed passwords together with their salt and run them through the hashing algorithm. bcrypt is explicitly designed to make that process take time, so you'll spend far longer trying to crack a password than just scan through a list of 200 million passwords and search for the known hash in a database.
So what do you do when computers gets even faster? You increase the 12 parameter - the rounds - this increases the runtime of the hashing alogrithm, hopefully staying safer for even longer (you can experiment with the rounds parameter to passlib.hash).

Using WebCrypto to generate a key pair useful for both encryption and signing

In Chrome this fails:
window.crypto.subtle.generateKey(
{
name: "RSA-OAEP",
modulusLength: 4096,
hash: {name: "SHA-256"},
},
true,
["sign", "verify", "encrypt", "decrypt"]
)
Why is this not possible? Why I cannot create a key pair which could be used for both encryption and signing? RSA keys by themselves do not have this limitation.
RSA-OAEP means that the encryption algorithm RSA and the padding scheme OAEP are used. OAEP is only specified for encryption and not for signing. For example, you can look into the source code of Firefox to find the corresponding check.
If you want to sign something, then you need to use "RSA-PSS".
You cannot directly use the same RSA key reference for both encryption and signing, and you should never use the same key for different operations.

how can i set blowfish for CRYPT_BLOWFISH function in php

i use this code for encrypt my data to blwofish but i dont know really to convert to blowfish or other encryption.
echo crypt('ab','$2a$09$anexamplestringforsalt$')."\n";
and i'm try bottom code but it's false
echo CRYPT_BLOWFISH('ab','$2a$09$anexamplestringforsalt$')."\n";
It is the crypt parameter string, that defines which algorithm is used:
$2a : This describes the algorithm (BCrypt) but should be 2y nowadays
$09 : This is the number of rounds and is usually 10 or higher
$anexamplestringforsalt : This should be a really random salt of a given alphabet
To generate a BCrypt hash, it is much safer to use the new password_hash() function though, there exists also a compatibility pack for earlier PHP versions.
// Hash a new password for storing in the database.
// The function automatically generates a cryptographically safe salt.
$hashToStoreInDb = password_hash($password, PASSWORD_BCRYPT);
// Check if the hash of the entered login password, matches the stored hash.
// The salt and the cost factor will be extracted from $existingHashFromDb.
$isPasswordCorrect = password_verify($password, $existingHashFromDb);

TCL code that can encrypt and decrypt a string

I need a piece of code that defines functions which can encrypt and decrypt a piece of string. What I basically want is that the string should not be visible to third-party users, so that when the string originates in one file, it is converted to, say, an integer value using the encrypt function and then it is passed as parameter to another file. There the decrpyt function then decrypts it back and uses the string to perform actions on it.
Any suggestions or already available codes will be just fine!
Please help me out. Thanks!
Install tcllib. There are several standard encryption algorithms implemented in tcllib.
The following encryption algorithms are available:
blowfish: http://tcllib.sourceforge.net/doc/blowfish.html
aes: http://tcllib.sourceforge.net/doc/aes.html
des (including triple des): http://tcllib.sourceforge.net/doc/des.html
rc4: http://tcllib.sourceforge.net/doc/rc4.html
The des package in Tcllib should do what you want. It's pretty easy to use:
package require des
set key "12345678"; # Must be 8 bytes long
set msg "abcde"
##### ENCRYPTION
set encryptedMsg [DES::des -dir encrypt -key $key $msg]
# $encryptedMsg is a bunch of bytes; you'll want to send this around...
##### DECRYPTION
set decryptedMsg [DES::des -dir decrypt -key $key $encryptedMsg]
puts "I got '$decryptedMsg'"
Note that DES will pad the message out to a multiple of 8 bytes long.
Please visit the TCL/TK homepage e.g
here:http://wiki.tcl.tk/900
That's just one way of doing it. There will be much more, I'm sure.

Resources