Is it safe to split the output of PBKDF2?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP












2












$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.



  1. User enters email and password;

  2. Derive k <- pbkdf2(password: password, salt: email, alg: 'sha256', iteration: 10000, dkLen: 512);

  3. Split k into (k0, k1) = (k[0:255], k[256:512]). Use k0 as client side key and send k1 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?










share|improve this question











$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 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




    $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
















2












$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.



  1. User enters email and password;

  2. Derive k <- pbkdf2(password: password, salt: email, alg: 'sha256', iteration: 10000, dkLen: 512);

  3. Split k into (k0, k1) = (k[0:255], k[256:512]). Use k0 as client side key and send k1 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?










share|improve this question











$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 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




    $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














2












2








2





$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.



  1. User enters email and password;

  2. Derive k <- pbkdf2(password: password, salt: email, alg: 'sha256', iteration: 10000, dkLen: 512);

  3. Split k into (k0, k1) = (k[0:255], k[256:512]). Use k0 as client side key and send k1 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?










share|improve this question











$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.



  1. User enters email and password;

  2. Derive k <- pbkdf2(password: password, salt: email, alg: 'sha256', iteration: 10000, dkLen: 512);

  3. Split k into (k0, k1) = (k[0:255], k[256:512]). Use k0 as client side key and send k1 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






share|improve this question















share|improve this question













share|improve this question




share|improve this question








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 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




    $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$
    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




    $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











1 Answer
1






active

oldest

votes


















5












$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.






share|improve this answer









$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 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










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
);



);













draft saved

draft discarded


















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









5












$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.






share|improve this answer









$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 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















5












$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.






share|improve this answer









$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 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













5












5








5





$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.






share|improve this answer









$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.







share|improve this answer












share|improve this answer



share|improve this answer










answered Jan 30 at 21:02









Maarten BodewesMaarten 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 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$
    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 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$
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

















draft saved

draft discarded
















































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.




draft saved


draft discarded














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





















































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






Popular posts from this blog

How to check contact read email or not when send email to Individual?

Bahrain

Postfix configuration issue with fips on centos 7; mailgun relay