Is it safe to split the output of PBKDF2?
Clash Royale CLAN TAG#URR8PPP
$begingroup$
I would like to know if splitting a key generated by PBKDF2 to derive two keys is a safe practice.
Concretely, in my system, I need to derive two keys. One for symmetric cipher used in the client side, and one for authenticating the user by sending to the server. The first key is never sent to the server so that only the client knows how to decrypt ciphertexts.
- User enters email and password;
- Derive
k <- pbkdf2(password: password, salt: email, alg: 'sha256', iteration: 10000, dkLen: 512)
; - Split
k
into(k0, k1) = (k[0:255], k[256:512])
. Usek0
as client side key and sendk1
to the server.
My idea is that there is no risk in splitting the key in such manner because the key is a pseudo-random string. Any ideas?
key-derivation pbkdf-2
$endgroup$
|
show 2 more comments
$begingroup$
I would like to know if splitting a key generated by PBKDF2 to derive two keys is a safe practice.
Concretely, in my system, I need to derive two keys. One for symmetric cipher used in the client side, and one for authenticating the user by sending to the server. The first key is never sent to the server so that only the client knows how to decrypt ciphertexts.
- User enters email and password;
- Derive
k <- pbkdf2(password: password, salt: email, alg: 'sha256', iteration: 10000, dkLen: 512)
; - Split
k
into(k0, k1) = (k[0:255], k[256:512])
. Usek0
as client side key and sendk1
to the server.
My idea is that there is no risk in splitting the key in such manner because the key is a pseudo-random string. Any ideas?
key-derivation pbkdf-2
$endgroup$
$begingroup$
Does second paragraph need rewriting? Why not use two different salts to generate two keys?
$endgroup$
– kelalaka
Jan 30 at 20:13
$begingroup$
Note that you should not storek1
at the server without an additional hash. Otherwise an adversary may find a copy of the DB and directly sendk1
to the service to log in; the adversary would not require the password anymore for your service, even if the password is still secure.
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:07
1
$begingroup$
@kelalaka It's better to run one PB-KDF once than two PB-KDFs that are each half as strong. Use a key-based KDF to derive your keys from one master key. Unfortunately PBKDF2 does things the wrong way, making the defender do at least twice as much work if dkLen > hLen while not doubling the password cracker's work.
$endgroup$
– Future Security
Jan 30 at 21:08
2
$begingroup$
Yep, two calculations with a different salt would not solve this; you would still have to perform two calculations to calculate k0 and k1, while the adversary only needs to perform one of them to guess the password input.
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:12
$begingroup$
@FutureSecurity you are right, The question has changed that I understood better, now. Splitting and sending half is not a good idea. Using two passwords may be better.
$endgroup$
– kelalaka
Jan 30 at 21:17
|
show 2 more comments
$begingroup$
I would like to know if splitting a key generated by PBKDF2 to derive two keys is a safe practice.
Concretely, in my system, I need to derive two keys. One for symmetric cipher used in the client side, and one for authenticating the user by sending to the server. The first key is never sent to the server so that only the client knows how to decrypt ciphertexts.
- User enters email and password;
- Derive
k <- pbkdf2(password: password, salt: email, alg: 'sha256', iteration: 10000, dkLen: 512)
; - Split
k
into(k0, k1) = (k[0:255], k[256:512])
. Usek0
as client side key and sendk1
to the server.
My idea is that there is no risk in splitting the key in such manner because the key is a pseudo-random string. Any ideas?
key-derivation pbkdf-2
$endgroup$
I would like to know if splitting a key generated by PBKDF2 to derive two keys is a safe practice.
Concretely, in my system, I need to derive two keys. One for symmetric cipher used in the client side, and one for authenticating the user by sending to the server. The first key is never sent to the server so that only the client knows how to decrypt ciphertexts.
- User enters email and password;
- Derive
k <- pbkdf2(password: password, salt: email, alg: 'sha256', iteration: 10000, dkLen: 512)
; - Split
k
into(k0, k1) = (k[0:255], k[256:512])
. Usek0
as client side key and sendk1
to the server.
My idea is that there is no risk in splitting the key in such manner because the key is a pseudo-random string. Any ideas?
key-derivation pbkdf-2
key-derivation pbkdf-2
edited Jan 30 at 21:23
Maarten Bodewes♦
54.8k679194
54.8k679194
asked Jan 30 at 20:10
Sung Won ChoSung Won Cho
1256
1256
$begingroup$
Does second paragraph need rewriting? Why not use two different salts to generate two keys?
$endgroup$
– kelalaka
Jan 30 at 20:13
$begingroup$
Note that you should not storek1
at the server without an additional hash. Otherwise an adversary may find a copy of the DB and directly sendk1
to the service to log in; the adversary would not require the password anymore for your service, even if the password is still secure.
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:07
1
$begingroup$
@kelalaka It's better to run one PB-KDF once than two PB-KDFs that are each half as strong. Use a key-based KDF to derive your keys from one master key. Unfortunately PBKDF2 does things the wrong way, making the defender do at least twice as much work if dkLen > hLen while not doubling the password cracker's work.
$endgroup$
– Future Security
Jan 30 at 21:08
2
$begingroup$
Yep, two calculations with a different salt would not solve this; you would still have to perform two calculations to calculate k0 and k1, while the adversary only needs to perform one of them to guess the password input.
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:12
$begingroup$
@FutureSecurity you are right, The question has changed that I understood better, now. Splitting and sending half is not a good idea. Using two passwords may be better.
$endgroup$
– kelalaka
Jan 30 at 21:17
|
show 2 more comments
$begingroup$
Does second paragraph need rewriting? Why not use two different salts to generate two keys?
$endgroup$
– kelalaka
Jan 30 at 20:13
$begingroup$
Note that you should not storek1
at the server without an additional hash. Otherwise an adversary may find a copy of the DB and directly sendk1
to the service to log in; the adversary would not require the password anymore for your service, even if the password is still secure.
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:07
1
$begingroup$
@kelalaka It's better to run one PB-KDF once than two PB-KDFs that are each half as strong. Use a key-based KDF to derive your keys from one master key. Unfortunately PBKDF2 does things the wrong way, making the defender do at least twice as much work if dkLen > hLen while not doubling the password cracker's work.
$endgroup$
– Future Security
Jan 30 at 21:08
2
$begingroup$
Yep, two calculations with a different salt would not solve this; you would still have to perform two calculations to calculate k0 and k1, while the adversary only needs to perform one of them to guess the password input.
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:12
$begingroup$
@FutureSecurity you are right, The question has changed that I understood better, now. Splitting and sending half is not a good idea. Using two passwords may be better.
$endgroup$
– kelalaka
Jan 30 at 21:17
$begingroup$
Does second paragraph need rewriting? Why not use two different salts to generate two keys?
$endgroup$
– kelalaka
Jan 30 at 20:13
$begingroup$
Does second paragraph need rewriting? Why not use two different salts to generate two keys?
$endgroup$
– kelalaka
Jan 30 at 20:13
$begingroup$
Note that you should not store
k1
at the server without an additional hash. Otherwise an adversary may find a copy of the DB and directly send k1
to the service to log in; the adversary would not require the password anymore for your service, even if the password is still secure.$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:07
$begingroup$
Note that you should not store
k1
at the server without an additional hash. Otherwise an adversary may find a copy of the DB and directly send k1
to the service to log in; the adversary would not require the password anymore for your service, even if the password is still secure.$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:07
1
1
$begingroup$
@kelalaka It's better to run one PB-KDF once than two PB-KDFs that are each half as strong. Use a key-based KDF to derive your keys from one master key. Unfortunately PBKDF2 does things the wrong way, making the defender do at least twice as much work if dkLen > hLen while not doubling the password cracker's work.
$endgroup$
– Future Security
Jan 30 at 21:08
$begingroup$
@kelalaka It's better to run one PB-KDF once than two PB-KDFs that are each half as strong. Use a key-based KDF to derive your keys from one master key. Unfortunately PBKDF2 does things the wrong way, making the defender do at least twice as much work if dkLen > hLen while not doubling the password cracker's work.
$endgroup$
– Future Security
Jan 30 at 21:08
2
2
$begingroup$
Yep, two calculations with a different salt would not solve this; you would still have to perform two calculations to calculate k0 and k1, while the adversary only needs to perform one of them to guess the password input.
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:12
$begingroup$
Yep, two calculations with a different salt would not solve this; you would still have to perform two calculations to calculate k0 and k1, while the adversary only needs to perform one of them to guess the password input.
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:12
$begingroup$
@FutureSecurity you are right, The question has changed that I understood better, now. Splitting and sending half is not a good idea. Using two passwords may be better.
$endgroup$
– kelalaka
Jan 30 at 21:17
$begingroup$
@FutureSecurity you are right, The question has changed that I understood better, now. Splitting and sending half is not a good idea. Using two passwords may be better.
$endgroup$
– kelalaka
Jan 30 at 21:17
|
show 2 more comments
1 Answer
1
active
oldest
votes
$begingroup$
It's secure as the bits are unrelated. It is not secure because it removes a bit of security by giving advantage to an attacker.
PBKDF2 has indeed been defined to generate a dynamic amount of key material. The bits of the output are independent of each other, and having any part of the output doesn't give you any information about the rest of the output values. So $k_0$ and $k_1$ are unrelated because PBKDF2 is indeed a pseudo random generator. Great.
However, PBKDF2 has also a design problem: if you require more than the output of the hash function (in this case SHA-256) then it requires you to perform all the iterations again to calculate the next block of output. This is problematic as an adversary may not need to perform those calculations themselves.
For instance, if the attacker just needs to compare against a value encrypted with $k_0$ then the adversary doesn't need to calculate $k_1$: just calculating and validating $k_0$ is enough to guess the password. You, on the other hand, need $k_1$ so you will have to perform all that work without gaining any advantage from it. As the adversary only needs half the work, obviously you lose one bit of secure. And, as your keys are both the exact output size of the hash function, you've inadvertently made it easy for the adversary.
There are a few ways around this. First of all, you can use a more modern function such as Argon2 (check for secure Argon2 configurations first). Secondly, it is possible to use the output of PBKDF2 and derive two keys from it using a key based key derivation function or KBKDF such as HKDF, e.g. k0 = HKDF(k, "Enc")
and k1 = HKDF(k, "Auth")
.
Finally, you can "hack" PBKDF2 by using SHA-512 and have it deliver 512 bits, which you can split. That's solution obviously doesn't scale well, but it is useful if the other options are not available to you, and it is very simple to achieve; you just have to change the hash function after all.
$endgroup$
$begingroup$
Note that "one bit of security" is not much if you're talking about e.g. an AES-256 key. However, the work factor of PBKDF2 doesn't provide nowhere near that kind of security, especially with a relatively low iteration count of 10000. Of course, given the last two solutions, you can double the iteration count without increasing the CPU time (much).
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:21
$begingroup$
What about first generate the encryption key k0 with the password then using the generated key as password to arrive k1?
$endgroup$
– kelalaka
Jan 30 at 21:22
$begingroup$
If you also use k0 to encrypt something (which seems to be the use case) then you can still test the password against k0 without involving k1, and you would still be doing twice the work. k1 would now also depend on k0. Actually, that may be worse than the double salt solution.
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:25
$begingroup$
But the k0 only used in client side. Assuming the keys are correctly removed the system after enc/dec who will know the k0?
$endgroup$
– kelalaka
Jan 30 at 21:28
$begingroup$
Thanks for your answer. @kelalaka, interesting, I think your suggestion has an advantage in that the client does not have to send a secret keyk0
to the server. In other words, it does not have to trust the server. Althoughk1
depends onk0
, sincek0
is a pseudo-random string, attacker cannot efficiently reversek1
to obtaink0
. What do you think?
$endgroup$
– Sung Won Cho
Jan 30 at 21:34
|
show 2 more comments
Your Answer
StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["$", "$"], ["\\(","\\)"]]);
);
);
, "mathjax-editing");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "281"
;
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: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
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
,
noCode: 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%2fcrypto.stackexchange.com%2fquestions%2f66915%2fis-it-safe-to-split-the-output-of-pbkdf2%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
It's secure as the bits are unrelated. It is not secure because it removes a bit of security by giving advantage to an attacker.
PBKDF2 has indeed been defined to generate a dynamic amount of key material. The bits of the output are independent of each other, and having any part of the output doesn't give you any information about the rest of the output values. So $k_0$ and $k_1$ are unrelated because PBKDF2 is indeed a pseudo random generator. Great.
However, PBKDF2 has also a design problem: if you require more than the output of the hash function (in this case SHA-256) then it requires you to perform all the iterations again to calculate the next block of output. This is problematic as an adversary may not need to perform those calculations themselves.
For instance, if the attacker just needs to compare against a value encrypted with $k_0$ then the adversary doesn't need to calculate $k_1$: just calculating and validating $k_0$ is enough to guess the password. You, on the other hand, need $k_1$ so you will have to perform all that work without gaining any advantage from it. As the adversary only needs half the work, obviously you lose one bit of secure. And, as your keys are both the exact output size of the hash function, you've inadvertently made it easy for the adversary.
There are a few ways around this. First of all, you can use a more modern function such as Argon2 (check for secure Argon2 configurations first). Secondly, it is possible to use the output of PBKDF2 and derive two keys from it using a key based key derivation function or KBKDF such as HKDF, e.g. k0 = HKDF(k, "Enc")
and k1 = HKDF(k, "Auth")
.
Finally, you can "hack" PBKDF2 by using SHA-512 and have it deliver 512 bits, which you can split. That's solution obviously doesn't scale well, but it is useful if the other options are not available to you, and it is very simple to achieve; you just have to change the hash function after all.
$endgroup$
$begingroup$
Note that "one bit of security" is not much if you're talking about e.g. an AES-256 key. However, the work factor of PBKDF2 doesn't provide nowhere near that kind of security, especially with a relatively low iteration count of 10000. Of course, given the last two solutions, you can double the iteration count without increasing the CPU time (much).
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:21
$begingroup$
What about first generate the encryption key k0 with the password then using the generated key as password to arrive k1?
$endgroup$
– kelalaka
Jan 30 at 21:22
$begingroup$
If you also use k0 to encrypt something (which seems to be the use case) then you can still test the password against k0 without involving k1, and you would still be doing twice the work. k1 would now also depend on k0. Actually, that may be worse than the double salt solution.
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:25
$begingroup$
But the k0 only used in client side. Assuming the keys are correctly removed the system after enc/dec who will know the k0?
$endgroup$
– kelalaka
Jan 30 at 21:28
$begingroup$
Thanks for your answer. @kelalaka, interesting, I think your suggestion has an advantage in that the client does not have to send a secret keyk0
to the server. In other words, it does not have to trust the server. Althoughk1
depends onk0
, sincek0
is a pseudo-random string, attacker cannot efficiently reversek1
to obtaink0
. What do you think?
$endgroup$
– Sung Won Cho
Jan 30 at 21:34
|
show 2 more comments
$begingroup$
It's secure as the bits are unrelated. It is not secure because it removes a bit of security by giving advantage to an attacker.
PBKDF2 has indeed been defined to generate a dynamic amount of key material. The bits of the output are independent of each other, and having any part of the output doesn't give you any information about the rest of the output values. So $k_0$ and $k_1$ are unrelated because PBKDF2 is indeed a pseudo random generator. Great.
However, PBKDF2 has also a design problem: if you require more than the output of the hash function (in this case SHA-256) then it requires you to perform all the iterations again to calculate the next block of output. This is problematic as an adversary may not need to perform those calculations themselves.
For instance, if the attacker just needs to compare against a value encrypted with $k_0$ then the adversary doesn't need to calculate $k_1$: just calculating and validating $k_0$ is enough to guess the password. You, on the other hand, need $k_1$ so you will have to perform all that work without gaining any advantage from it. As the adversary only needs half the work, obviously you lose one bit of secure. And, as your keys are both the exact output size of the hash function, you've inadvertently made it easy for the adversary.
There are a few ways around this. First of all, you can use a more modern function such as Argon2 (check for secure Argon2 configurations first). Secondly, it is possible to use the output of PBKDF2 and derive two keys from it using a key based key derivation function or KBKDF such as HKDF, e.g. k0 = HKDF(k, "Enc")
and k1 = HKDF(k, "Auth")
.
Finally, you can "hack" PBKDF2 by using SHA-512 and have it deliver 512 bits, which you can split. That's solution obviously doesn't scale well, but it is useful if the other options are not available to you, and it is very simple to achieve; you just have to change the hash function after all.
$endgroup$
$begingroup$
Note that "one bit of security" is not much if you're talking about e.g. an AES-256 key. However, the work factor of PBKDF2 doesn't provide nowhere near that kind of security, especially with a relatively low iteration count of 10000. Of course, given the last two solutions, you can double the iteration count without increasing the CPU time (much).
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:21
$begingroup$
What about first generate the encryption key k0 with the password then using the generated key as password to arrive k1?
$endgroup$
– kelalaka
Jan 30 at 21:22
$begingroup$
If you also use k0 to encrypt something (which seems to be the use case) then you can still test the password against k0 without involving k1, and you would still be doing twice the work. k1 would now also depend on k0. Actually, that may be worse than the double salt solution.
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:25
$begingroup$
But the k0 only used in client side. Assuming the keys are correctly removed the system after enc/dec who will know the k0?
$endgroup$
– kelalaka
Jan 30 at 21:28
$begingroup$
Thanks for your answer. @kelalaka, interesting, I think your suggestion has an advantage in that the client does not have to send a secret keyk0
to the server. In other words, it does not have to trust the server. Althoughk1
depends onk0
, sincek0
is a pseudo-random string, attacker cannot efficiently reversek1
to obtaink0
. What do you think?
$endgroup$
– Sung Won Cho
Jan 30 at 21:34
|
show 2 more comments
$begingroup$
It's secure as the bits are unrelated. It is not secure because it removes a bit of security by giving advantage to an attacker.
PBKDF2 has indeed been defined to generate a dynamic amount of key material. The bits of the output are independent of each other, and having any part of the output doesn't give you any information about the rest of the output values. So $k_0$ and $k_1$ are unrelated because PBKDF2 is indeed a pseudo random generator. Great.
However, PBKDF2 has also a design problem: if you require more than the output of the hash function (in this case SHA-256) then it requires you to perform all the iterations again to calculate the next block of output. This is problematic as an adversary may not need to perform those calculations themselves.
For instance, if the attacker just needs to compare against a value encrypted with $k_0$ then the adversary doesn't need to calculate $k_1$: just calculating and validating $k_0$ is enough to guess the password. You, on the other hand, need $k_1$ so you will have to perform all that work without gaining any advantage from it. As the adversary only needs half the work, obviously you lose one bit of secure. And, as your keys are both the exact output size of the hash function, you've inadvertently made it easy for the adversary.
There are a few ways around this. First of all, you can use a more modern function such as Argon2 (check for secure Argon2 configurations first). Secondly, it is possible to use the output of PBKDF2 and derive two keys from it using a key based key derivation function or KBKDF such as HKDF, e.g. k0 = HKDF(k, "Enc")
and k1 = HKDF(k, "Auth")
.
Finally, you can "hack" PBKDF2 by using SHA-512 and have it deliver 512 bits, which you can split. That's solution obviously doesn't scale well, but it is useful if the other options are not available to you, and it is very simple to achieve; you just have to change the hash function after all.
$endgroup$
It's secure as the bits are unrelated. It is not secure because it removes a bit of security by giving advantage to an attacker.
PBKDF2 has indeed been defined to generate a dynamic amount of key material. The bits of the output are independent of each other, and having any part of the output doesn't give you any information about the rest of the output values. So $k_0$ and $k_1$ are unrelated because PBKDF2 is indeed a pseudo random generator. Great.
However, PBKDF2 has also a design problem: if you require more than the output of the hash function (in this case SHA-256) then it requires you to perform all the iterations again to calculate the next block of output. This is problematic as an adversary may not need to perform those calculations themselves.
For instance, if the attacker just needs to compare against a value encrypted with $k_0$ then the adversary doesn't need to calculate $k_1$: just calculating and validating $k_0$ is enough to guess the password. You, on the other hand, need $k_1$ so you will have to perform all that work without gaining any advantage from it. As the adversary only needs half the work, obviously you lose one bit of secure. And, as your keys are both the exact output size of the hash function, you've inadvertently made it easy for the adversary.
There are a few ways around this. First of all, you can use a more modern function such as Argon2 (check for secure Argon2 configurations first). Secondly, it is possible to use the output of PBKDF2 and derive two keys from it using a key based key derivation function or KBKDF such as HKDF, e.g. k0 = HKDF(k, "Enc")
and k1 = HKDF(k, "Auth")
.
Finally, you can "hack" PBKDF2 by using SHA-512 and have it deliver 512 bits, which you can split. That's solution obviously doesn't scale well, but it is useful if the other options are not available to you, and it is very simple to achieve; you just have to change the hash function after all.
answered Jan 30 at 21:02
Maarten Bodewes♦Maarten Bodewes
54.8k679194
54.8k679194
$begingroup$
Note that "one bit of security" is not much if you're talking about e.g. an AES-256 key. However, the work factor of PBKDF2 doesn't provide nowhere near that kind of security, especially with a relatively low iteration count of 10000. Of course, given the last two solutions, you can double the iteration count without increasing the CPU time (much).
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:21
$begingroup$
What about first generate the encryption key k0 with the password then using the generated key as password to arrive k1?
$endgroup$
– kelalaka
Jan 30 at 21:22
$begingroup$
If you also use k0 to encrypt something (which seems to be the use case) then you can still test the password against k0 without involving k1, and you would still be doing twice the work. k1 would now also depend on k0. Actually, that may be worse than the double salt solution.
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:25
$begingroup$
But the k0 only used in client side. Assuming the keys are correctly removed the system after enc/dec who will know the k0?
$endgroup$
– kelalaka
Jan 30 at 21:28
$begingroup$
Thanks for your answer. @kelalaka, interesting, I think your suggestion has an advantage in that the client does not have to send a secret keyk0
to the server. In other words, it does not have to trust the server. Althoughk1
depends onk0
, sincek0
is a pseudo-random string, attacker cannot efficiently reversek1
to obtaink0
. What do you think?
$endgroup$
– Sung Won Cho
Jan 30 at 21:34
|
show 2 more comments
$begingroup$
Note that "one bit of security" is not much if you're talking about e.g. an AES-256 key. However, the work factor of PBKDF2 doesn't provide nowhere near that kind of security, especially with a relatively low iteration count of 10000. Of course, given the last two solutions, you can double the iteration count without increasing the CPU time (much).
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:21
$begingroup$
What about first generate the encryption key k0 with the password then using the generated key as password to arrive k1?
$endgroup$
– kelalaka
Jan 30 at 21:22
$begingroup$
If you also use k0 to encrypt something (which seems to be the use case) then you can still test the password against k0 without involving k1, and you would still be doing twice the work. k1 would now also depend on k0. Actually, that may be worse than the double salt solution.
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:25
$begingroup$
But the k0 only used in client side. Assuming the keys are correctly removed the system after enc/dec who will know the k0?
$endgroup$
– kelalaka
Jan 30 at 21:28
$begingroup$
Thanks for your answer. @kelalaka, interesting, I think your suggestion has an advantage in that the client does not have to send a secret keyk0
to the server. In other words, it does not have to trust the server. Althoughk1
depends onk0
, sincek0
is a pseudo-random string, attacker cannot efficiently reversek1
to obtaink0
. What do you think?
$endgroup$
– Sung Won Cho
Jan 30 at 21:34
$begingroup$
Note that "one bit of security" is not much if you're talking about e.g. an AES-256 key. However, the work factor of PBKDF2 doesn't provide nowhere near that kind of security, especially with a relatively low iteration count of 10000. Of course, given the last two solutions, you can double the iteration count without increasing the CPU time (much).
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:21
$begingroup$
Note that "one bit of security" is not much if you're talking about e.g. an AES-256 key. However, the work factor of PBKDF2 doesn't provide nowhere near that kind of security, especially with a relatively low iteration count of 10000. Of course, given the last two solutions, you can double the iteration count without increasing the CPU time (much).
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:21
$begingroup$
What about first generate the encryption key k0 with the password then using the generated key as password to arrive k1?
$endgroup$
– kelalaka
Jan 30 at 21:22
$begingroup$
What about first generate the encryption key k0 with the password then using the generated key as password to arrive k1?
$endgroup$
– kelalaka
Jan 30 at 21:22
$begingroup$
If you also use k0 to encrypt something (which seems to be the use case) then you can still test the password against k0 without involving k1, and you would still be doing twice the work. k1 would now also depend on k0. Actually, that may be worse than the double salt solution.
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:25
$begingroup$
If you also use k0 to encrypt something (which seems to be the use case) then you can still test the password against k0 without involving k1, and you would still be doing twice the work. k1 would now also depend on k0. Actually, that may be worse than the double salt solution.
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:25
$begingroup$
But the k0 only used in client side. Assuming the keys are correctly removed the system after enc/dec who will know the k0?
$endgroup$
– kelalaka
Jan 30 at 21:28
$begingroup$
But the k0 only used in client side. Assuming the keys are correctly removed the system after enc/dec who will know the k0?
$endgroup$
– kelalaka
Jan 30 at 21:28
$begingroup$
Thanks for your answer. @kelalaka, interesting, I think your suggestion has an advantage in that the client does not have to send a secret key
k0
to the server. In other words, it does not have to trust the server. Although k1
depends on k0
, since k0
is a pseudo-random string, attacker cannot efficiently reverse k1
to obtain k0
. What do you think?$endgroup$
– Sung Won Cho
Jan 30 at 21:34
$begingroup$
Thanks for your answer. @kelalaka, interesting, I think your suggestion has an advantage in that the client does not have to send a secret key
k0
to the server. In other words, it does not have to trust the server. Although k1
depends on k0
, since k0
is a pseudo-random string, attacker cannot efficiently reverse k1
to obtain k0
. What do you think?$endgroup$
– Sung Won Cho
Jan 30 at 21:34
|
show 2 more comments
Thanks for contributing an answer to Cryptography Stack Exchange!
- 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.
Use MathJax to format equations. MathJax reference.
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%2fcrypto.stackexchange.com%2fquestions%2f66915%2fis-it-safe-to-split-the-output-of-pbkdf2%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
$begingroup$
Does second paragraph need rewriting? Why not use two different salts to generate two keys?
$endgroup$
– kelalaka
Jan 30 at 20:13
$begingroup$
Note that you should not store
k1
at the server without an additional hash. Otherwise an adversary may find a copy of the DB and directly sendk1
to the service to log in; the adversary would not require the password anymore for your service, even if the password is still secure.$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:07
1
$begingroup$
@kelalaka It's better to run one PB-KDF once than two PB-KDFs that are each half as strong. Use a key-based KDF to derive your keys from one master key. Unfortunately PBKDF2 does things the wrong way, making the defender do at least twice as much work if dkLen > hLen while not doubling the password cracker's work.
$endgroup$
– Future Security
Jan 30 at 21:08
2
$begingroup$
Yep, two calculations with a different salt would not solve this; you would still have to perform two calculations to calculate k0 and k1, while the adversary only needs to perform one of them to guess the password input.
$endgroup$
– Maarten Bodewes♦
Jan 30 at 21:12
$begingroup$
@FutureSecurity you are right, The question has changed that I understood better, now. Splitting and sending half is not a good idea. Using two passwords may be better.
$endgroup$
– kelalaka
Jan 30 at 21:17