Is it necessary to use key derivation when using Node's 'crypto' module? Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 23, 2019 at 00:00UTC (8:00pm US/Eastern) Data science time! April 2019 and salary with experience The Ask Question Wizard is Live!When is a CDATA section necessary within a script tag?Java 256-bit AES Password-Based EncryptionHow to decide when to use Node.js?Javascript by reference vs. by valueIs Safari on iOS 6 caching $.ajax results?Using ursa (nodejs module) to generate a symmetric key?Camel PGP crypto and symmetric keysSymmetric Encryption with GPGMEDoes NodeJS https perform symmetric encryption of the trafficEncryption/decryption using publickey | Crypto Module | NodeJS
Disembodied hand growing fangs
How to tell that you are a giant?
Why wasn't DOSKEY integrated with COMMAND.COM?
What is a fractional matching?
Do I really need to have a message in a novel to appeal to readers?
Using audio cues to encourage good posture
What does it mean that physics no longer uses mechanical models to describe phenomena?
SF book about people trapped in a series of worlds they imagine
How does the math work when buying airline miles?
Did Deadpool rescue all of the X-Force?
Why is the AVR GCC compiler using a full `CALL` even though I have set the `-mshort-calls` flag?
What is the appropriate index architecture when forced to implement IsDeleted (soft deletes)?
How often does castling occur in grandmaster games?
How to compare two different files line by line in unix?
Denied boarding although I have proper visa and documentation. To whom should I make a complaint?
Why do early math courses focus on the cross sections of a cone and not on other 3D objects?
Is CEO the "profession" with the most psychopaths?
As a beginner, should I get a Squier Strat with a SSS config or a HSS?
Can anything be seen from the center of the Boötes void? How dark would it be?
Amount of permutations on an NxNxN Rubik's Cube
The code below, is it ill-formed NDR or is it well formed?
How fail-safe is nr as stop bytes?
How to write this math term? with cases it isn't working
Selecting user stories during sprint planning
Is it necessary to use key derivation when using Node's 'crypto' module?
Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 23, 2019 at 00:00UTC (8:00pm US/Eastern)
Data science time! April 2019 and salary with experience
The Ask Question Wizard is Live!When is a CDATA section necessary within a script tag?Java 256-bit AES Password-Based EncryptionHow to decide when to use Node.js?Javascript by reference vs. by valueIs Safari on iOS 6 caching $.ajax results?Using ursa (nodejs module) to generate a symmetric key?Camel PGP crypto and symmetric keysSymmetric Encryption with GPGMEDoes NodeJS https perform symmetric encryption of the trafficEncryption/decryption using publickey | Crypto Module | NodeJS
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I need to implement symmetric encryption using a user's passphrase in a NodeJS application. When using crypto.createCipheriv()
, do I need to perform some sort of key derivation on the passphrase to obtain a value for the key
parameter, or is it sufficient to just pass the user's passphrase as-is and this is taken care of by the implementation?
javascript node.js encryption
|
show 1 more comment
I need to implement symmetric encryption using a user's passphrase in a NodeJS application. When using crypto.createCipheriv()
, do I need to perform some sort of key derivation on the passphrase to obtain a value for the key
parameter, or is it sufficient to just pass the user's passphrase as-is and this is taken care of by the implementation?
javascript node.js encryption
Im not entirely understanding, what you want to do. you want to create a symmetric encryption using a passphrase of the user, and you will have it on the server side so will be able to use it as a seed in both sides? I'm not following what are you willing to do with these pieces. Are you willing to use a key separation technique or you just want to successfully and securely get a symmetric key?
– Daniel Vega
Mar 7 at 15:42
1
createCipheriv()
doesn't modify the user specified key, so yes, if you have a password you should use a KDF.
– t.m.adam
Mar 7 at 18:08
@DanielVega - no, this is an Electron app and encryption is for data being synchronized
– millimoose
Mar 7 at 19:08
@t.m.adam Thanks, that’s probably closest to what I’m looking for. Is my intuition that not stretching the passphrase is a Bad Idea correct? (My current thinking is to shove the passphrase and the user ID - both generated using nanoid that claims to produce sound character distributions from a CSPRNG - into Argon2; with only the ID ever existing outside the user’s device as cleartext, the derived key cached on it, the passphrase as close to never as is possible on the platform.)
– millimoose
Mar 8 at 18:32
1
Yes, never use a password as key. Argon2 is a very good KDF, but it's not supported bycrypto
as far as I know. I'll post an answer using PBKDF2/scrypt if you're interested.
– t.m.adam
Mar 8 at 18:45
|
show 1 more comment
I need to implement symmetric encryption using a user's passphrase in a NodeJS application. When using crypto.createCipheriv()
, do I need to perform some sort of key derivation on the passphrase to obtain a value for the key
parameter, or is it sufficient to just pass the user's passphrase as-is and this is taken care of by the implementation?
javascript node.js encryption
I need to implement symmetric encryption using a user's passphrase in a NodeJS application. When using crypto.createCipheriv()
, do I need to perform some sort of key derivation on the passphrase to obtain a value for the key
parameter, or is it sufficient to just pass the user's passphrase as-is and this is taken care of by the implementation?
javascript node.js encryption
javascript node.js encryption
asked Mar 5 at 2:07
millimoosemillimoose
32.6k763106
32.6k763106
Im not entirely understanding, what you want to do. you want to create a symmetric encryption using a passphrase of the user, and you will have it on the server side so will be able to use it as a seed in both sides? I'm not following what are you willing to do with these pieces. Are you willing to use a key separation technique or you just want to successfully and securely get a symmetric key?
– Daniel Vega
Mar 7 at 15:42
1
createCipheriv()
doesn't modify the user specified key, so yes, if you have a password you should use a KDF.
– t.m.adam
Mar 7 at 18:08
@DanielVega - no, this is an Electron app and encryption is for data being synchronized
– millimoose
Mar 7 at 19:08
@t.m.adam Thanks, that’s probably closest to what I’m looking for. Is my intuition that not stretching the passphrase is a Bad Idea correct? (My current thinking is to shove the passphrase and the user ID - both generated using nanoid that claims to produce sound character distributions from a CSPRNG - into Argon2; with only the ID ever existing outside the user’s device as cleartext, the derived key cached on it, the passphrase as close to never as is possible on the platform.)
– millimoose
Mar 8 at 18:32
1
Yes, never use a password as key. Argon2 is a very good KDF, but it's not supported bycrypto
as far as I know. I'll post an answer using PBKDF2/scrypt if you're interested.
– t.m.adam
Mar 8 at 18:45
|
show 1 more comment
Im not entirely understanding, what you want to do. you want to create a symmetric encryption using a passphrase of the user, and you will have it on the server side so will be able to use it as a seed in both sides? I'm not following what are you willing to do with these pieces. Are you willing to use a key separation technique or you just want to successfully and securely get a symmetric key?
– Daniel Vega
Mar 7 at 15:42
1
createCipheriv()
doesn't modify the user specified key, so yes, if you have a password you should use a KDF.
– t.m.adam
Mar 7 at 18:08
@DanielVega - no, this is an Electron app and encryption is for data being synchronized
– millimoose
Mar 7 at 19:08
@t.m.adam Thanks, that’s probably closest to what I’m looking for. Is my intuition that not stretching the passphrase is a Bad Idea correct? (My current thinking is to shove the passphrase and the user ID - both generated using nanoid that claims to produce sound character distributions from a CSPRNG - into Argon2; with only the ID ever existing outside the user’s device as cleartext, the derived key cached on it, the passphrase as close to never as is possible on the platform.)
– millimoose
Mar 8 at 18:32
1
Yes, never use a password as key. Argon2 is a very good KDF, but it's not supported bycrypto
as far as I know. I'll post an answer using PBKDF2/scrypt if you're interested.
– t.m.adam
Mar 8 at 18:45
Im not entirely understanding, what you want to do. you want to create a symmetric encryption using a passphrase of the user, and you will have it on the server side so will be able to use it as a seed in both sides? I'm not following what are you willing to do with these pieces. Are you willing to use a key separation technique or you just want to successfully and securely get a symmetric key?
– Daniel Vega
Mar 7 at 15:42
Im not entirely understanding, what you want to do. you want to create a symmetric encryption using a passphrase of the user, and you will have it on the server side so will be able to use it as a seed in both sides? I'm not following what are you willing to do with these pieces. Are you willing to use a key separation technique or you just want to successfully and securely get a symmetric key?
– Daniel Vega
Mar 7 at 15:42
1
1
createCipheriv()
doesn't modify the user specified key, so yes, if you have a password you should use a KDF.– t.m.adam
Mar 7 at 18:08
createCipheriv()
doesn't modify the user specified key, so yes, if you have a password you should use a KDF.– t.m.adam
Mar 7 at 18:08
@DanielVega - no, this is an Electron app and encryption is for data being synchronized
– millimoose
Mar 7 at 19:08
@DanielVega - no, this is an Electron app and encryption is for data being synchronized
– millimoose
Mar 7 at 19:08
@t.m.adam Thanks, that’s probably closest to what I’m looking for. Is my intuition that not stretching the passphrase is a Bad Idea correct? (My current thinking is to shove the passphrase and the user ID - both generated using nanoid that claims to produce sound character distributions from a CSPRNG - into Argon2; with only the ID ever existing outside the user’s device as cleartext, the derived key cached on it, the passphrase as close to never as is possible on the platform.)
– millimoose
Mar 8 at 18:32
@t.m.adam Thanks, that’s probably closest to what I’m looking for. Is my intuition that not stretching the passphrase is a Bad Idea correct? (My current thinking is to shove the passphrase and the user ID - both generated using nanoid that claims to produce sound character distributions from a CSPRNG - into Argon2; with only the ID ever existing outside the user’s device as cleartext, the derived key cached on it, the passphrase as close to never as is possible on the platform.)
– millimoose
Mar 8 at 18:32
1
1
Yes, never use a password as key. Argon2 is a very good KDF, but it's not supported by
crypto
as far as I know. I'll post an answer using PBKDF2/scrypt if you're interested.– t.m.adam
Mar 8 at 18:45
Yes, never use a password as key. Argon2 is a very good KDF, but it's not supported by
crypto
as far as I know. I'll post an answer using PBKDF2/scrypt if you're interested.– t.m.adam
Mar 8 at 18:45
|
show 1 more comment
2 Answers
2
active
oldest
votes
Passwords should not be used as keys directly, but they can be used to produce a key with a KDF. That is because a key is expected to have a certain size and because passwords are weak - they use only a limited set of bytes and they usually contain words. This makes them vulnerable to both brute-force and dictionary attacks. KDFs not only produce strong keys, but they also introduce a work factor which makes brute-force attacks impractical.
createCipheriv()
does not modify the key contents or size. This is not mentioned in the documentation, but following the source code (from createCipheriv
: source, to Cipheriv
: source, to createCipherWithIV
: source, to prepareSecretKey
: source) we see that the key is used as it is. So, the key is expected to have the right size and it should have enough complexity.
Crypto provides two password-based KDFs, scrypt and PBKDF2. It would be best to use scrypt because it is very expensive in terms of CPU and memory resources and it can be adjusted for parallel processing, while PBKDF2 only costs CPU resources. Both KDFs require a salt, which should be long and random.
Creating a key with scrypt
:
const keySize = 16; // for AES-128
const salt = crypto.randomBytes(16);
const key = crypto.scryptSync('password', salt, keySize);
Creating a key with pbkdf2
:
const keySize = 16; // for AES-128
const salt = crypto.randomBytes(16);
const key = crypto.pbkdf2Sync('password', salt, 10000, keySize, 'sha256');
Where 'sha256' is the underlying hash and 10000 is the recommend minimum number of iterations, that determines the work factor. In scrypt the general work factor is an optional parameter with default value 16384 (2^14), and can be set in options['cost']
, where we can also set the block size and parallelization. Those values can be increased quite a lot, depending on the OS; each operation should take about 100 ms.
Finally, Argon2 is considered to be a very good KDF and like scrypt it can be adjusted for CPU and memory consumption and parallel processing. Although Argon2 it is not available in crypto
, it is provided by other Node.js packages.
add a comment |
The difficulty of breaking a cipher depends more on the used algorithm than the length of the password. (omitting brut-force attacks)
The key extension does not increase security, because you still have the same short password at the begining. For your safety, immediately assume that you had a break-in and application code was leaked. That is, all standard and custom algorithms are public.
And you will have to use the password extension anyway, because most of the algorithms require a secret with a specific length.
An earlier answer, a little off topic.
TL;DR: The best way is to process the password into a binary buffer (string).
The symmetric encryption is precisely based on the fact that having the secret you are able to perform the reverse operation. Symetric mean operations are reversible.
Your programming language, framework or library does not matter.
Some differences are at the stage of packaging the encrypted message. You can receive a raw message, or a beautifully formatted message, where you have added IV and content in base64.
You also have to process the key in the same way. But it's about coding big endian
and little endian
and character encoding eg: utf-8
, latin2
IV
is an additional protection that aims to generate different encrypted messages for the same incoming message and secret. But as it is written in the last paragraph of the section you are targeting:
They do not have to be secret: IVs are typically just added to
ciphertext messages unencrypted.
In summary: you do not need to affect the encryption process itself, and you need to check what data the Electron needs.
For example my decrypt procedure (in node, data from PHP):
let crypto =
key: Buffer.from('secret in hex', 'hex'),
cipher: 'aes-128-cbc',
iv_size: 16
let bData = Buffer.from(data.replace(/ /g,'+'), 'base64');
let iv = bData.slice(0, crypto.iv_size);
let text = bData.slice(crypto.iv_size);
var decipher = crypt.createDecipheriv(crypto.cipher, crypto.key, iv);
decipher.setAutoPadding(false);
var decrypted = decipher.update(text,'hex','hex');
decrypted += decipher.final('hex');
For PHP encrypt:
$data = mcrypt_encrypt($this->_cipher, $this->_key, $data, $this->_mode, $iv);
// Use base64 encoding to convert to a string
return base64_encode($iv.$data);
//where
array(
'key'=> urldecode('secret in urlencode'),
'cipher' => MCRYPT_RIJNDAEL_128,
'mode' => MCRYPT_MODE_CBC,
),
As you can see, I had to find the encryption algorithms implemented on both platforms, and provide a way to provide an identical key on both platforms.
I’m not sure what this has to do with my question though? I (think I) know roughly how to roundtrip data through a cipher, I was asking if it’s fine from a security standpoint to use the passphrase directly as input to the cipher, or if I should stretch it with a KDF. Clearly either will “work” as in allow for encrypting then decrypting the data correctly for parties that know the passphrase and KDF if applicable; I’m concerned about whether not using a KDF in my code will make it easier for an attacker to decrypt the data.
– millimoose
Mar 8 at 18:04
i.e. I’m asking about how to correctly produce the “secret” in your example code, something that happens before everything you’re covering. As for my comment you say you’re reacting to, assuming you mean my answer to Daniel Vega, I just cleared up what seemed to be his assumption that when I say “NodeJS”, I mean a server-side application and that a server is storing a user’s passphrase, which would make using symmetric encryption with such a passphrase pointless to begin with. But I’m not doing that.
– millimoose
Mar 8 at 18:07
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54994413%2fis-it-necessary-to-use-key-derivation-when-using-nodes-crypto-module%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Passwords should not be used as keys directly, but they can be used to produce a key with a KDF. That is because a key is expected to have a certain size and because passwords are weak - they use only a limited set of bytes and they usually contain words. This makes them vulnerable to both brute-force and dictionary attacks. KDFs not only produce strong keys, but they also introduce a work factor which makes brute-force attacks impractical.
createCipheriv()
does not modify the key contents or size. This is not mentioned in the documentation, but following the source code (from createCipheriv
: source, to Cipheriv
: source, to createCipherWithIV
: source, to prepareSecretKey
: source) we see that the key is used as it is. So, the key is expected to have the right size and it should have enough complexity.
Crypto provides two password-based KDFs, scrypt and PBKDF2. It would be best to use scrypt because it is very expensive in terms of CPU and memory resources and it can be adjusted for parallel processing, while PBKDF2 only costs CPU resources. Both KDFs require a salt, which should be long and random.
Creating a key with scrypt
:
const keySize = 16; // for AES-128
const salt = crypto.randomBytes(16);
const key = crypto.scryptSync('password', salt, keySize);
Creating a key with pbkdf2
:
const keySize = 16; // for AES-128
const salt = crypto.randomBytes(16);
const key = crypto.pbkdf2Sync('password', salt, 10000, keySize, 'sha256');
Where 'sha256' is the underlying hash and 10000 is the recommend minimum number of iterations, that determines the work factor. In scrypt the general work factor is an optional parameter with default value 16384 (2^14), and can be set in options['cost']
, where we can also set the block size and parallelization. Those values can be increased quite a lot, depending on the OS; each operation should take about 100 ms.
Finally, Argon2 is considered to be a very good KDF and like scrypt it can be adjusted for CPU and memory consumption and parallel processing. Although Argon2 it is not available in crypto
, it is provided by other Node.js packages.
add a comment |
Passwords should not be used as keys directly, but they can be used to produce a key with a KDF. That is because a key is expected to have a certain size and because passwords are weak - they use only a limited set of bytes and they usually contain words. This makes them vulnerable to both brute-force and dictionary attacks. KDFs not only produce strong keys, but they also introduce a work factor which makes brute-force attacks impractical.
createCipheriv()
does not modify the key contents or size. This is not mentioned in the documentation, but following the source code (from createCipheriv
: source, to Cipheriv
: source, to createCipherWithIV
: source, to prepareSecretKey
: source) we see that the key is used as it is. So, the key is expected to have the right size and it should have enough complexity.
Crypto provides two password-based KDFs, scrypt and PBKDF2. It would be best to use scrypt because it is very expensive in terms of CPU and memory resources and it can be adjusted for parallel processing, while PBKDF2 only costs CPU resources. Both KDFs require a salt, which should be long and random.
Creating a key with scrypt
:
const keySize = 16; // for AES-128
const salt = crypto.randomBytes(16);
const key = crypto.scryptSync('password', salt, keySize);
Creating a key with pbkdf2
:
const keySize = 16; // for AES-128
const salt = crypto.randomBytes(16);
const key = crypto.pbkdf2Sync('password', salt, 10000, keySize, 'sha256');
Where 'sha256' is the underlying hash and 10000 is the recommend minimum number of iterations, that determines the work factor. In scrypt the general work factor is an optional parameter with default value 16384 (2^14), and can be set in options['cost']
, where we can also set the block size and parallelization. Those values can be increased quite a lot, depending on the OS; each operation should take about 100 ms.
Finally, Argon2 is considered to be a very good KDF and like scrypt it can be adjusted for CPU and memory consumption and parallel processing. Although Argon2 it is not available in crypto
, it is provided by other Node.js packages.
add a comment |
Passwords should not be used as keys directly, but they can be used to produce a key with a KDF. That is because a key is expected to have a certain size and because passwords are weak - they use only a limited set of bytes and they usually contain words. This makes them vulnerable to both brute-force and dictionary attacks. KDFs not only produce strong keys, but they also introduce a work factor which makes brute-force attacks impractical.
createCipheriv()
does not modify the key contents or size. This is not mentioned in the documentation, but following the source code (from createCipheriv
: source, to Cipheriv
: source, to createCipherWithIV
: source, to prepareSecretKey
: source) we see that the key is used as it is. So, the key is expected to have the right size and it should have enough complexity.
Crypto provides two password-based KDFs, scrypt and PBKDF2. It would be best to use scrypt because it is very expensive in terms of CPU and memory resources and it can be adjusted for parallel processing, while PBKDF2 only costs CPU resources. Both KDFs require a salt, which should be long and random.
Creating a key with scrypt
:
const keySize = 16; // for AES-128
const salt = crypto.randomBytes(16);
const key = crypto.scryptSync('password', salt, keySize);
Creating a key with pbkdf2
:
const keySize = 16; // for AES-128
const salt = crypto.randomBytes(16);
const key = crypto.pbkdf2Sync('password', salt, 10000, keySize, 'sha256');
Where 'sha256' is the underlying hash and 10000 is the recommend minimum number of iterations, that determines the work factor. In scrypt the general work factor is an optional parameter with default value 16384 (2^14), and can be set in options['cost']
, where we can also set the block size and parallelization. Those values can be increased quite a lot, depending on the OS; each operation should take about 100 ms.
Finally, Argon2 is considered to be a very good KDF and like scrypt it can be adjusted for CPU and memory consumption and parallel processing. Although Argon2 it is not available in crypto
, it is provided by other Node.js packages.
Passwords should not be used as keys directly, but they can be used to produce a key with a KDF. That is because a key is expected to have a certain size and because passwords are weak - they use only a limited set of bytes and they usually contain words. This makes them vulnerable to both brute-force and dictionary attacks. KDFs not only produce strong keys, but they also introduce a work factor which makes brute-force attacks impractical.
createCipheriv()
does not modify the key contents or size. This is not mentioned in the documentation, but following the source code (from createCipheriv
: source, to Cipheriv
: source, to createCipherWithIV
: source, to prepareSecretKey
: source) we see that the key is used as it is. So, the key is expected to have the right size and it should have enough complexity.
Crypto provides two password-based KDFs, scrypt and PBKDF2. It would be best to use scrypt because it is very expensive in terms of CPU and memory resources and it can be adjusted for parallel processing, while PBKDF2 only costs CPU resources. Both KDFs require a salt, which should be long and random.
Creating a key with scrypt
:
const keySize = 16; // for AES-128
const salt = crypto.randomBytes(16);
const key = crypto.scryptSync('password', salt, keySize);
Creating a key with pbkdf2
:
const keySize = 16; // for AES-128
const salt = crypto.randomBytes(16);
const key = crypto.pbkdf2Sync('password', salt, 10000, keySize, 'sha256');
Where 'sha256' is the underlying hash and 10000 is the recommend minimum number of iterations, that determines the work factor. In scrypt the general work factor is an optional parameter with default value 16384 (2^14), and can be set in options['cost']
, where we can also set the block size and parallelization. Those values can be increased quite a lot, depending on the OS; each operation should take about 100 ms.
Finally, Argon2 is considered to be a very good KDF and like scrypt it can be adjusted for CPU and memory consumption and parallel processing. Although Argon2 it is not available in crypto
, it is provided by other Node.js packages.
answered Mar 10 at 19:37
t.m.adamt.m.adam
11.6k31537
11.6k31537
add a comment |
add a comment |
The difficulty of breaking a cipher depends more on the used algorithm than the length of the password. (omitting brut-force attacks)
The key extension does not increase security, because you still have the same short password at the begining. For your safety, immediately assume that you had a break-in and application code was leaked. That is, all standard and custom algorithms are public.
And you will have to use the password extension anyway, because most of the algorithms require a secret with a specific length.
An earlier answer, a little off topic.
TL;DR: The best way is to process the password into a binary buffer (string).
The symmetric encryption is precisely based on the fact that having the secret you are able to perform the reverse operation. Symetric mean operations are reversible.
Your programming language, framework or library does not matter.
Some differences are at the stage of packaging the encrypted message. You can receive a raw message, or a beautifully formatted message, where you have added IV and content in base64.
You also have to process the key in the same way. But it's about coding big endian
and little endian
and character encoding eg: utf-8
, latin2
IV
is an additional protection that aims to generate different encrypted messages for the same incoming message and secret. But as it is written in the last paragraph of the section you are targeting:
They do not have to be secret: IVs are typically just added to
ciphertext messages unencrypted.
In summary: you do not need to affect the encryption process itself, and you need to check what data the Electron needs.
For example my decrypt procedure (in node, data from PHP):
let crypto =
key: Buffer.from('secret in hex', 'hex'),
cipher: 'aes-128-cbc',
iv_size: 16
let bData = Buffer.from(data.replace(/ /g,'+'), 'base64');
let iv = bData.slice(0, crypto.iv_size);
let text = bData.slice(crypto.iv_size);
var decipher = crypt.createDecipheriv(crypto.cipher, crypto.key, iv);
decipher.setAutoPadding(false);
var decrypted = decipher.update(text,'hex','hex');
decrypted += decipher.final('hex');
For PHP encrypt:
$data = mcrypt_encrypt($this->_cipher, $this->_key, $data, $this->_mode, $iv);
// Use base64 encoding to convert to a string
return base64_encode($iv.$data);
//where
array(
'key'=> urldecode('secret in urlencode'),
'cipher' => MCRYPT_RIJNDAEL_128,
'mode' => MCRYPT_MODE_CBC,
),
As you can see, I had to find the encryption algorithms implemented on both platforms, and provide a way to provide an identical key on both platforms.
I’m not sure what this has to do with my question though? I (think I) know roughly how to roundtrip data through a cipher, I was asking if it’s fine from a security standpoint to use the passphrase directly as input to the cipher, or if I should stretch it with a KDF. Clearly either will “work” as in allow for encrypting then decrypting the data correctly for parties that know the passphrase and KDF if applicable; I’m concerned about whether not using a KDF in my code will make it easier for an attacker to decrypt the data.
– millimoose
Mar 8 at 18:04
i.e. I’m asking about how to correctly produce the “secret” in your example code, something that happens before everything you’re covering. As for my comment you say you’re reacting to, assuming you mean my answer to Daniel Vega, I just cleared up what seemed to be his assumption that when I say “NodeJS”, I mean a server-side application and that a server is storing a user’s passphrase, which would make using symmetric encryption with such a passphrase pointless to begin with. But I’m not doing that.
– millimoose
Mar 8 at 18:07
add a comment |
The difficulty of breaking a cipher depends more on the used algorithm than the length of the password. (omitting brut-force attacks)
The key extension does not increase security, because you still have the same short password at the begining. For your safety, immediately assume that you had a break-in and application code was leaked. That is, all standard and custom algorithms are public.
And you will have to use the password extension anyway, because most of the algorithms require a secret with a specific length.
An earlier answer, a little off topic.
TL;DR: The best way is to process the password into a binary buffer (string).
The symmetric encryption is precisely based on the fact that having the secret you are able to perform the reverse operation. Symetric mean operations are reversible.
Your programming language, framework or library does not matter.
Some differences are at the stage of packaging the encrypted message. You can receive a raw message, or a beautifully formatted message, where you have added IV and content in base64.
You also have to process the key in the same way. But it's about coding big endian
and little endian
and character encoding eg: utf-8
, latin2
IV
is an additional protection that aims to generate different encrypted messages for the same incoming message and secret. But as it is written in the last paragraph of the section you are targeting:
They do not have to be secret: IVs are typically just added to
ciphertext messages unencrypted.
In summary: you do not need to affect the encryption process itself, and you need to check what data the Electron needs.
For example my decrypt procedure (in node, data from PHP):
let crypto =
key: Buffer.from('secret in hex', 'hex'),
cipher: 'aes-128-cbc',
iv_size: 16
let bData = Buffer.from(data.replace(/ /g,'+'), 'base64');
let iv = bData.slice(0, crypto.iv_size);
let text = bData.slice(crypto.iv_size);
var decipher = crypt.createDecipheriv(crypto.cipher, crypto.key, iv);
decipher.setAutoPadding(false);
var decrypted = decipher.update(text,'hex','hex');
decrypted += decipher.final('hex');
For PHP encrypt:
$data = mcrypt_encrypt($this->_cipher, $this->_key, $data, $this->_mode, $iv);
// Use base64 encoding to convert to a string
return base64_encode($iv.$data);
//where
array(
'key'=> urldecode('secret in urlencode'),
'cipher' => MCRYPT_RIJNDAEL_128,
'mode' => MCRYPT_MODE_CBC,
),
As you can see, I had to find the encryption algorithms implemented on both platforms, and provide a way to provide an identical key on both platforms.
I’m not sure what this has to do with my question though? I (think I) know roughly how to roundtrip data through a cipher, I was asking if it’s fine from a security standpoint to use the passphrase directly as input to the cipher, or if I should stretch it with a KDF. Clearly either will “work” as in allow for encrypting then decrypting the data correctly for parties that know the passphrase and KDF if applicable; I’m concerned about whether not using a KDF in my code will make it easier for an attacker to decrypt the data.
– millimoose
Mar 8 at 18:04
i.e. I’m asking about how to correctly produce the “secret” in your example code, something that happens before everything you’re covering. As for my comment you say you’re reacting to, assuming you mean my answer to Daniel Vega, I just cleared up what seemed to be his assumption that when I say “NodeJS”, I mean a server-side application and that a server is storing a user’s passphrase, which would make using symmetric encryption with such a passphrase pointless to begin with. But I’m not doing that.
– millimoose
Mar 8 at 18:07
add a comment |
The difficulty of breaking a cipher depends more on the used algorithm than the length of the password. (omitting brut-force attacks)
The key extension does not increase security, because you still have the same short password at the begining. For your safety, immediately assume that you had a break-in and application code was leaked. That is, all standard and custom algorithms are public.
And you will have to use the password extension anyway, because most of the algorithms require a secret with a specific length.
An earlier answer, a little off topic.
TL;DR: The best way is to process the password into a binary buffer (string).
The symmetric encryption is precisely based on the fact that having the secret you are able to perform the reverse operation. Symetric mean operations are reversible.
Your programming language, framework or library does not matter.
Some differences are at the stage of packaging the encrypted message. You can receive a raw message, or a beautifully formatted message, where you have added IV and content in base64.
You also have to process the key in the same way. But it's about coding big endian
and little endian
and character encoding eg: utf-8
, latin2
IV
is an additional protection that aims to generate different encrypted messages for the same incoming message and secret. But as it is written in the last paragraph of the section you are targeting:
They do not have to be secret: IVs are typically just added to
ciphertext messages unencrypted.
In summary: you do not need to affect the encryption process itself, and you need to check what data the Electron needs.
For example my decrypt procedure (in node, data from PHP):
let crypto =
key: Buffer.from('secret in hex', 'hex'),
cipher: 'aes-128-cbc',
iv_size: 16
let bData = Buffer.from(data.replace(/ /g,'+'), 'base64');
let iv = bData.slice(0, crypto.iv_size);
let text = bData.slice(crypto.iv_size);
var decipher = crypt.createDecipheriv(crypto.cipher, crypto.key, iv);
decipher.setAutoPadding(false);
var decrypted = decipher.update(text,'hex','hex');
decrypted += decipher.final('hex');
For PHP encrypt:
$data = mcrypt_encrypt($this->_cipher, $this->_key, $data, $this->_mode, $iv);
// Use base64 encoding to convert to a string
return base64_encode($iv.$data);
//where
array(
'key'=> urldecode('secret in urlencode'),
'cipher' => MCRYPT_RIJNDAEL_128,
'mode' => MCRYPT_MODE_CBC,
),
As you can see, I had to find the encryption algorithms implemented on both platforms, and provide a way to provide an identical key on both platforms.
The difficulty of breaking a cipher depends more on the used algorithm than the length of the password. (omitting brut-force attacks)
The key extension does not increase security, because you still have the same short password at the begining. For your safety, immediately assume that you had a break-in and application code was leaked. That is, all standard and custom algorithms are public.
And you will have to use the password extension anyway, because most of the algorithms require a secret with a specific length.
An earlier answer, a little off topic.
TL;DR: The best way is to process the password into a binary buffer (string).
The symmetric encryption is precisely based on the fact that having the secret you are able to perform the reverse operation. Symetric mean operations are reversible.
Your programming language, framework or library does not matter.
Some differences are at the stage of packaging the encrypted message. You can receive a raw message, or a beautifully formatted message, where you have added IV and content in base64.
You also have to process the key in the same way. But it's about coding big endian
and little endian
and character encoding eg: utf-8
, latin2
IV
is an additional protection that aims to generate different encrypted messages for the same incoming message and secret. But as it is written in the last paragraph of the section you are targeting:
They do not have to be secret: IVs are typically just added to
ciphertext messages unencrypted.
In summary: you do not need to affect the encryption process itself, and you need to check what data the Electron needs.
For example my decrypt procedure (in node, data from PHP):
let crypto =
key: Buffer.from('secret in hex', 'hex'),
cipher: 'aes-128-cbc',
iv_size: 16
let bData = Buffer.from(data.replace(/ /g,'+'), 'base64');
let iv = bData.slice(0, crypto.iv_size);
let text = bData.slice(crypto.iv_size);
var decipher = crypt.createDecipheriv(crypto.cipher, crypto.key, iv);
decipher.setAutoPadding(false);
var decrypted = decipher.update(text,'hex','hex');
decrypted += decipher.final('hex');
For PHP encrypt:
$data = mcrypt_encrypt($this->_cipher, $this->_key, $data, $this->_mode, $iv);
// Use base64 encoding to convert to a string
return base64_encode($iv.$data);
//where
array(
'key'=> urldecode('secret in urlencode'),
'cipher' => MCRYPT_RIJNDAEL_128,
'mode' => MCRYPT_MODE_CBC,
),
As you can see, I had to find the encryption algorithms implemented on both platforms, and provide a way to provide an identical key on both platforms.
edited Mar 8 at 20:22
answered Mar 8 at 9:04
bato3bato3
1,83811020
1,83811020
I’m not sure what this has to do with my question though? I (think I) know roughly how to roundtrip data through a cipher, I was asking if it’s fine from a security standpoint to use the passphrase directly as input to the cipher, or if I should stretch it with a KDF. Clearly either will “work” as in allow for encrypting then decrypting the data correctly for parties that know the passphrase and KDF if applicable; I’m concerned about whether not using a KDF in my code will make it easier for an attacker to decrypt the data.
– millimoose
Mar 8 at 18:04
i.e. I’m asking about how to correctly produce the “secret” in your example code, something that happens before everything you’re covering. As for my comment you say you’re reacting to, assuming you mean my answer to Daniel Vega, I just cleared up what seemed to be his assumption that when I say “NodeJS”, I mean a server-side application and that a server is storing a user’s passphrase, which would make using symmetric encryption with such a passphrase pointless to begin with. But I’m not doing that.
– millimoose
Mar 8 at 18:07
add a comment |
I’m not sure what this has to do with my question though? I (think I) know roughly how to roundtrip data through a cipher, I was asking if it’s fine from a security standpoint to use the passphrase directly as input to the cipher, or if I should stretch it with a KDF. Clearly either will “work” as in allow for encrypting then decrypting the data correctly for parties that know the passphrase and KDF if applicable; I’m concerned about whether not using a KDF in my code will make it easier for an attacker to decrypt the data.
– millimoose
Mar 8 at 18:04
i.e. I’m asking about how to correctly produce the “secret” in your example code, something that happens before everything you’re covering. As for my comment you say you’re reacting to, assuming you mean my answer to Daniel Vega, I just cleared up what seemed to be his assumption that when I say “NodeJS”, I mean a server-side application and that a server is storing a user’s passphrase, which would make using symmetric encryption with such a passphrase pointless to begin with. But I’m not doing that.
– millimoose
Mar 8 at 18:07
I’m not sure what this has to do with my question though? I (think I) know roughly how to roundtrip data through a cipher, I was asking if it’s fine from a security standpoint to use the passphrase directly as input to the cipher, or if I should stretch it with a KDF. Clearly either will “work” as in allow for encrypting then decrypting the data correctly for parties that know the passphrase and KDF if applicable; I’m concerned about whether not using a KDF in my code will make it easier for an attacker to decrypt the data.
– millimoose
Mar 8 at 18:04
I’m not sure what this has to do with my question though? I (think I) know roughly how to roundtrip data through a cipher, I was asking if it’s fine from a security standpoint to use the passphrase directly as input to the cipher, or if I should stretch it with a KDF. Clearly either will “work” as in allow for encrypting then decrypting the data correctly for parties that know the passphrase and KDF if applicable; I’m concerned about whether not using a KDF in my code will make it easier for an attacker to decrypt the data.
– millimoose
Mar 8 at 18:04
i.e. I’m asking about how to correctly produce the “secret” in your example code, something that happens before everything you’re covering. As for my comment you say you’re reacting to, assuming you mean my answer to Daniel Vega, I just cleared up what seemed to be his assumption that when I say “NodeJS”, I mean a server-side application and that a server is storing a user’s passphrase, which would make using symmetric encryption with such a passphrase pointless to begin with. But I’m not doing that.
– millimoose
Mar 8 at 18:07
i.e. I’m asking about how to correctly produce the “secret” in your example code, something that happens before everything you’re covering. As for my comment you say you’re reacting to, assuming you mean my answer to Daniel Vega, I just cleared up what seemed to be his assumption that when I say “NodeJS”, I mean a server-side application and that a server is storing a user’s passphrase, which would make using symmetric encryption with such a passphrase pointless to begin with. But I’m not doing that.
– millimoose
Mar 8 at 18:07
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54994413%2fis-it-necessary-to-use-key-derivation-when-using-nodes-crypto-module%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Im not entirely understanding, what you want to do. you want to create a symmetric encryption using a passphrase of the user, and you will have it on the server side so will be able to use it as a seed in both sides? I'm not following what are you willing to do with these pieces. Are you willing to use a key separation technique or you just want to successfully and securely get a symmetric key?
– Daniel Vega
Mar 7 at 15:42
1
createCipheriv()
doesn't modify the user specified key, so yes, if you have a password you should use a KDF.– t.m.adam
Mar 7 at 18:08
@DanielVega - no, this is an Electron app and encryption is for data being synchronized
– millimoose
Mar 7 at 19:08
@t.m.adam Thanks, that’s probably closest to what I’m looking for. Is my intuition that not stretching the passphrase is a Bad Idea correct? (My current thinking is to shove the passphrase and the user ID - both generated using nanoid that claims to produce sound character distributions from a CSPRNG - into Argon2; with only the ID ever existing outside the user’s device as cleartext, the derived key cached on it, the passphrase as close to never as is possible on the platform.)
– millimoose
Mar 8 at 18:32
1
Yes, never use a password as key. Argon2 is a very good KDF, but it's not supported by
crypto
as far as I know. I'll post an answer using PBKDF2/scrypt if you're interested.– t.m.adam
Mar 8 at 18:45