Does appending randomness to a token before encrypting it, make it more secure?

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





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
5
down vote

favorite
3












Scenario:



  • User requests page on my site

  • Server builds up token using various values, encrypts it (via an industry-standard algorithm, nothing homegrown) using a key only the server knows, and returns it as part of the page data

  • Token is embedded into link on page

  • When client clicks that link, token is sent to server, decrypted and parsed and the values used to determine what to do

This is done because we need certain bits of information to be sent from the client to the server, but we don't want to leak those bits of information to the client because they would reveal details of the server's inner workings.



The issue here is that, every time a particular user views a particular page, the same token will be generated for them. Apart from allowing the same request to be replayed against the endpoint ad infinitum, this makes it more likely that someone will be able to break the token encryption (yes, I know this isn't likely, but it is possible).



To make the encryption even more resilient, my intention is to insert a high-quality random value - say a GUID - into the token before it is encrypted. The end result will be to introduce more entropy into the encryption process, meaning that for a given set of identical values that we care about (i.e. everything except the random value), the generated token will almost certainly differ. This random value will always be inserted in the same place and will always be the same length, so removing and throwing it away after the token is decrypted is trivial. Effectively, this is augmenting encryption with obfuscation.



It appears to my untrained eye that this is a relatively simple and safe solution to my problem, but is it, or am I just wasting my time and/or making things less secure and more complicated?







share|improve this question




















  • i would consider a standard approach like JWT, which includes space for your side-car meta
    – dandavis
    Aug 30 at 18:47










  • Which encryption algorithm do you use?
    – Sjoerd
    Aug 30 at 19:14






  • 1




    Why should the secret leave the server in the first place? Generate a random token. That one is given to the client. The secret data is stored on the server, with the token as lookup key. Client sends token to server. Server looks up values in database. A secret can't be compromised if you don't give it away.If the token is used on another server, make that server talk to the original server over an encrypted channel. If the client isn't supposed to have the data, don't give it to him.
    – Polygnome
    Aug 30 at 20:51
















up vote
5
down vote

favorite
3












Scenario:



  • User requests page on my site

  • Server builds up token using various values, encrypts it (via an industry-standard algorithm, nothing homegrown) using a key only the server knows, and returns it as part of the page data

  • Token is embedded into link on page

  • When client clicks that link, token is sent to server, decrypted and parsed and the values used to determine what to do

This is done because we need certain bits of information to be sent from the client to the server, but we don't want to leak those bits of information to the client because they would reveal details of the server's inner workings.



The issue here is that, every time a particular user views a particular page, the same token will be generated for them. Apart from allowing the same request to be replayed against the endpoint ad infinitum, this makes it more likely that someone will be able to break the token encryption (yes, I know this isn't likely, but it is possible).



To make the encryption even more resilient, my intention is to insert a high-quality random value - say a GUID - into the token before it is encrypted. The end result will be to introduce more entropy into the encryption process, meaning that for a given set of identical values that we care about (i.e. everything except the random value), the generated token will almost certainly differ. This random value will always be inserted in the same place and will always be the same length, so removing and throwing it away after the token is decrypted is trivial. Effectively, this is augmenting encryption with obfuscation.



It appears to my untrained eye that this is a relatively simple and safe solution to my problem, but is it, or am I just wasting my time and/or making things less secure and more complicated?







share|improve this question




















  • i would consider a standard approach like JWT, which includes space for your side-car meta
    – dandavis
    Aug 30 at 18:47










  • Which encryption algorithm do you use?
    – Sjoerd
    Aug 30 at 19:14






  • 1




    Why should the secret leave the server in the first place? Generate a random token. That one is given to the client. The secret data is stored on the server, with the token as lookup key. Client sends token to server. Server looks up values in database. A secret can't be compromised if you don't give it away.If the token is used on another server, make that server talk to the original server over an encrypted channel. If the client isn't supposed to have the data, don't give it to him.
    – Polygnome
    Aug 30 at 20:51












up vote
5
down vote

favorite
3









up vote
5
down vote

favorite
3






3





Scenario:



  • User requests page on my site

  • Server builds up token using various values, encrypts it (via an industry-standard algorithm, nothing homegrown) using a key only the server knows, and returns it as part of the page data

  • Token is embedded into link on page

  • When client clicks that link, token is sent to server, decrypted and parsed and the values used to determine what to do

This is done because we need certain bits of information to be sent from the client to the server, but we don't want to leak those bits of information to the client because they would reveal details of the server's inner workings.



The issue here is that, every time a particular user views a particular page, the same token will be generated for them. Apart from allowing the same request to be replayed against the endpoint ad infinitum, this makes it more likely that someone will be able to break the token encryption (yes, I know this isn't likely, but it is possible).



To make the encryption even more resilient, my intention is to insert a high-quality random value - say a GUID - into the token before it is encrypted. The end result will be to introduce more entropy into the encryption process, meaning that for a given set of identical values that we care about (i.e. everything except the random value), the generated token will almost certainly differ. This random value will always be inserted in the same place and will always be the same length, so removing and throwing it away after the token is decrypted is trivial. Effectively, this is augmenting encryption with obfuscation.



It appears to my untrained eye that this is a relatively simple and safe solution to my problem, but is it, or am I just wasting my time and/or making things less secure and more complicated?







share|improve this question












Scenario:



  • User requests page on my site

  • Server builds up token using various values, encrypts it (via an industry-standard algorithm, nothing homegrown) using a key only the server knows, and returns it as part of the page data

  • Token is embedded into link on page

  • When client clicks that link, token is sent to server, decrypted and parsed and the values used to determine what to do

This is done because we need certain bits of information to be sent from the client to the server, but we don't want to leak those bits of information to the client because they would reveal details of the server's inner workings.



The issue here is that, every time a particular user views a particular page, the same token will be generated for them. Apart from allowing the same request to be replayed against the endpoint ad infinitum, this makes it more likely that someone will be able to break the token encryption (yes, I know this isn't likely, but it is possible).



To make the encryption even more resilient, my intention is to insert a high-quality random value - say a GUID - into the token before it is encrypted. The end result will be to introduce more entropy into the encryption process, meaning that for a given set of identical values that we care about (i.e. everything except the random value), the generated token will almost certainly differ. This random value will always be inserted in the same place and will always be the same length, so removing and throwing it away after the token is decrypted is trivial. Effectively, this is augmenting encryption with obfuscation.



It appears to my untrained eye that this is a relatively simple and safe solution to my problem, but is it, or am I just wasting my time and/or making things less secure and more complicated?









share|improve this question











share|improve this question




share|improve this question










asked Aug 30 at 14:23









Ian Kemp

1567




1567











  • i would consider a standard approach like JWT, which includes space for your side-car meta
    – dandavis
    Aug 30 at 18:47










  • Which encryption algorithm do you use?
    – Sjoerd
    Aug 30 at 19:14






  • 1




    Why should the secret leave the server in the first place? Generate a random token. That one is given to the client. The secret data is stored on the server, with the token as lookup key. Client sends token to server. Server looks up values in database. A secret can't be compromised if you don't give it away.If the token is used on another server, make that server talk to the original server over an encrypted channel. If the client isn't supposed to have the data, don't give it to him.
    – Polygnome
    Aug 30 at 20:51
















  • i would consider a standard approach like JWT, which includes space for your side-car meta
    – dandavis
    Aug 30 at 18:47










  • Which encryption algorithm do you use?
    – Sjoerd
    Aug 30 at 19:14






  • 1




    Why should the secret leave the server in the first place? Generate a random token. That one is given to the client. The secret data is stored on the server, with the token as lookup key. Client sends token to server. Server looks up values in database. A secret can't be compromised if you don't give it away.If the token is used on another server, make that server talk to the original server over an encrypted channel. If the client isn't supposed to have the data, don't give it to him.
    – Polygnome
    Aug 30 at 20:51















i would consider a standard approach like JWT, which includes space for your side-car meta
– dandavis
Aug 30 at 18:47




i would consider a standard approach like JWT, which includes space for your side-car meta
– dandavis
Aug 30 at 18:47












Which encryption algorithm do you use?
– Sjoerd
Aug 30 at 19:14




Which encryption algorithm do you use?
– Sjoerd
Aug 30 at 19:14




1




1




Why should the secret leave the server in the first place? Generate a random token. That one is given to the client. The secret data is stored on the server, with the token as lookup key. Client sends token to server. Server looks up values in database. A secret can't be compromised if you don't give it away.If the token is used on another server, make that server talk to the original server over an encrypted channel. If the client isn't supposed to have the data, don't give it to him.
– Polygnome
Aug 30 at 20:51




Why should the secret leave the server in the first place? Generate a random token. That one is given to the client. The secret data is stored on the server, with the token as lookup key. Client sends token to server. Server looks up values in database. A secret can't be compromised if you don't give it away.If the token is used on another server, make that server talk to the original server over an encrypted channel. If the client isn't supposed to have the data, don't give it to him.
– Polygnome
Aug 30 at 20:51










4 Answers
4






active

oldest

votes

















up vote
15
down vote



accepted










You don't need to add any randomness to an encrypted token. If it's properly encrypted, user has no way to infer anything about the encrypted data.




The issue here is that, every time a particular user views a particular page, the same token will be generated for them.




This seems odd. Your encryption does not seem to use a secure standard. Otherwise every time you encrypted the same token, the cyphertext would change. You must use an IV, and never ever think about AES-ECB, that mode is broken and should not be used even to teach kids how AES works.



If you use industry standards, you will know about the Initialization Vector (IV). In rough terms, the IV is a value added to the process that changes the cyphertext, so even if you encrypt two identical plaintexts with the same key, the corresponding cyphertext will change.



The IV is the random data you are thinking about adding. It's already there.






share|improve this answer






















  • Since OP says that he sees the same token generated, I guess it's not properly encrypted with an IV. In that case, maybe he should add it or change what he's using for encryption to something that does add it for him.
    – JoL
    Aug 30 at 17:42










  • When encrypting a large amount of data, the cost of storing or transmitting an IV with the encrypted data will be usually be small relative to the cost of storing or transmitting everything else. If the payload is small, however, the cost of the IV relative to the payload may be more significant.
    – supercat
    Aug 30 at 21:08










  • If you don't use an IV and the data is small and predictable, you will disclose your key. And as you have one single key on the server, losing that key means disaster...
    – ThoriumBR
    Aug 30 at 23:40

















up vote
4
down vote













Let's try to break this down:



Problem: replaying a token:




Apart from allowing the same request to be replayed against the endpoint ad infinitum




Usually auth tokens solve this problem by expiring the tokens: the encrypted data includes a datestamp (which has the side-effect of making each token unique) and the server will reject any token older than, say 15 minutes.



Problem: breaking crypto:




this makes it more likely that someone will be able to break the token encryption




I'm not an expert, but it would seem to me that you should use a random IV for each encryption, and include the IV with the cipher text as part of the token. This would both solve the cryptanalysis problem you're alluding to, and have the side-effect of making your tokens unique. (if you're not using random IVs, then you probably have much bigger problems on your hands)



Why not use a standard library to do this rather than going out of your depth to design your own encryption scheme? I would recommend JWT.




Finally, as a public service I need to correct this: GUIDs ARE NOT HIGH-QUALITY RANDOMNESS.



See Wikipedia/Universally_unique_identifier.



UUIDs / GUIDs are designed to be unique, they make no attempt to be unpredictable. There are 5 standard ways to derive a UUID; 4 of them are some combination of MAC address + hostname + timestamp. Version 4 UUIDs are pure random, but because UUIDs / GUIDs generation needs to be fast and non-blocking, they use non-cryptographic random number generators.



PLEASE DO NOT USE UUIDs / GUIDs AS A SOURCE OF CRYPTOGRAPHIC RANDOMNESS. Instead use /dev/random in unix, SecureRandomin java, or whatever the equivalent is in your OS / programming language






share|improve this answer


















  • 2




    don't you mean /dev/urandom? devs shouldn't use /random for anything unless you are an expert making your own crypto system, and even then; don't roll your own crypto.
    – dandavis
    Aug 30 at 18:45







  • 3




    @dandavis uuuggggg I'm not getting into this debate again. They both have pros and cons. random is safer but may have performance issues, urandom is secure if your your system has been up for a while, is not an IoT device. etc. On most non-linux unixes /dev/random and /dev/urandom are symlinks to each other (ex. BSD, MacOS and iOS, Solaris (I think), AIX, etc). Personally I like FreeBSD's implementation better than linux's, but *shrug*. Basically: yes I know the difference, no I don't think they're significant enough to have yet another debate over.
    – Mike Ounsworth
    Aug 30 at 18:56







  • 1




    heh, no debate needed; i think your comment provides the context the answer missed...
    – dandavis
    Aug 30 at 19:02

















up vote
1
down vote













The solution that is used on my platform of choice is "encrypt/decrypt with managed IV (Initialization Vector)." What this means is that, upon encryption, the entire plain text is encrypted with a cryptographic secure IV, and then the IV is placed in base64-format before the beginning of the cipher text. Upon decryption, the IV is pulled off the front and used as the IV for the cipher text. This is all transparent to the developer. Note that it is perfectly safe to expose the IV, because decryption with the correct key but wrong IV will result in a failure condition. If your programming language has a similar feature, do use it; by having a random IV generated each time you encrypt something, you don't need to put any extra data in the plain text.






share|improve this answer



























    up vote
    0
    down vote













    To me, this looks like an XY Problem.



    The best way to protect a secret is not to tell anyone the secret. The token is generated server-side. The server already knows the data. And then you replay the token to the server, which contains only data the server already has. That is completely unnecessary.



    Other answers have pointed out the quick, immediate fix for your encryption problem by using encryption with IVs. But the better solution would be to make this superfluous.




    Server builds up token using various values, encrypts it (via an industry-standard algorithm, nothing homegrown) using a key only the server knows, and returns it as part of the page data




    Instead of encrypting those values, save them in a database. You can potentially, if you really must, still encrypt those values and then save them. But there is absolutely no need for these values to ever leave the server, even in encrypted form.
    Then generate a truly random token (with a CSPRNG), and use that as a lookup-key. Send this token to the client.




    Token is embedded into link on page




    Use the random token you just generated for that.




    When client clicks that link, token is sent to server, decrypted and parsed and the values used to determine what to do




    Instead of decrypting and parsing the values, you use the token to look them up in the database. Done. If you only stored the data encrypted, you still need to decrypt it, of course.



    This also works if you have multiple servers. If the token is generated on Server A and send to Server B, have Server B use a secure connection to Server A and request the data via the token from Server A. In this scenario, too, the data is never sent to the client.




    This is done because we need certain bits of information to be sent from the client to the server, but we don't want to leak those bits of information to the client because they would reveal details of the server's inner workings




    Internal state should never leak from an implementation. This is already a code smell and a good hint that your architecture is flawed.






    share|improve this answer






















      Your Answer







      StackExchange.ready(function()
      var channelOptions =
      tags: "".split(" "),
      id: "162"
      ;
      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',
      convertImagesToLinks: false,
      noModals: false,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: null,
      bindNavPrevention: true,
      postfix: "",
      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%2fsecurity.stackexchange.com%2fquestions%2f192731%2fdoes-appending-randomness-to-a-token-before-encrypting-it-make-it-more-secure%23new-answer', 'question_page');

      );

      Post as a guest






























      4 Answers
      4






      active

      oldest

      votes








      4 Answers
      4






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes








      up vote
      15
      down vote



      accepted










      You don't need to add any randomness to an encrypted token. If it's properly encrypted, user has no way to infer anything about the encrypted data.




      The issue here is that, every time a particular user views a particular page, the same token will be generated for them.




      This seems odd. Your encryption does not seem to use a secure standard. Otherwise every time you encrypted the same token, the cyphertext would change. You must use an IV, and never ever think about AES-ECB, that mode is broken and should not be used even to teach kids how AES works.



      If you use industry standards, you will know about the Initialization Vector (IV). In rough terms, the IV is a value added to the process that changes the cyphertext, so even if you encrypt two identical plaintexts with the same key, the corresponding cyphertext will change.



      The IV is the random data you are thinking about adding. It's already there.






      share|improve this answer






















      • Since OP says that he sees the same token generated, I guess it's not properly encrypted with an IV. In that case, maybe he should add it or change what he's using for encryption to something that does add it for him.
        – JoL
        Aug 30 at 17:42










      • When encrypting a large amount of data, the cost of storing or transmitting an IV with the encrypted data will be usually be small relative to the cost of storing or transmitting everything else. If the payload is small, however, the cost of the IV relative to the payload may be more significant.
        – supercat
        Aug 30 at 21:08










      • If you don't use an IV and the data is small and predictable, you will disclose your key. And as you have one single key on the server, losing that key means disaster...
        – ThoriumBR
        Aug 30 at 23:40














      up vote
      15
      down vote



      accepted










      You don't need to add any randomness to an encrypted token. If it's properly encrypted, user has no way to infer anything about the encrypted data.




      The issue here is that, every time a particular user views a particular page, the same token will be generated for them.




      This seems odd. Your encryption does not seem to use a secure standard. Otherwise every time you encrypted the same token, the cyphertext would change. You must use an IV, and never ever think about AES-ECB, that mode is broken and should not be used even to teach kids how AES works.



      If you use industry standards, you will know about the Initialization Vector (IV). In rough terms, the IV is a value added to the process that changes the cyphertext, so even if you encrypt two identical plaintexts with the same key, the corresponding cyphertext will change.



      The IV is the random data you are thinking about adding. It's already there.






      share|improve this answer






















      • Since OP says that he sees the same token generated, I guess it's not properly encrypted with an IV. In that case, maybe he should add it or change what he's using for encryption to something that does add it for him.
        – JoL
        Aug 30 at 17:42










      • When encrypting a large amount of data, the cost of storing or transmitting an IV with the encrypted data will be usually be small relative to the cost of storing or transmitting everything else. If the payload is small, however, the cost of the IV relative to the payload may be more significant.
        – supercat
        Aug 30 at 21:08










      • If you don't use an IV and the data is small and predictable, you will disclose your key. And as you have one single key on the server, losing that key means disaster...
        – ThoriumBR
        Aug 30 at 23:40












      up vote
      15
      down vote



      accepted







      up vote
      15
      down vote



      accepted






      You don't need to add any randomness to an encrypted token. If it's properly encrypted, user has no way to infer anything about the encrypted data.




      The issue here is that, every time a particular user views a particular page, the same token will be generated for them.




      This seems odd. Your encryption does not seem to use a secure standard. Otherwise every time you encrypted the same token, the cyphertext would change. You must use an IV, and never ever think about AES-ECB, that mode is broken and should not be used even to teach kids how AES works.



      If you use industry standards, you will know about the Initialization Vector (IV). In rough terms, the IV is a value added to the process that changes the cyphertext, so even if you encrypt two identical plaintexts with the same key, the corresponding cyphertext will change.



      The IV is the random data you are thinking about adding. It's already there.






      share|improve this answer














      You don't need to add any randomness to an encrypted token. If it's properly encrypted, user has no way to infer anything about the encrypted data.




      The issue here is that, every time a particular user views a particular page, the same token will be generated for them.




      This seems odd. Your encryption does not seem to use a secure standard. Otherwise every time you encrypted the same token, the cyphertext would change. You must use an IV, and never ever think about AES-ECB, that mode is broken and should not be used even to teach kids how AES works.



      If you use industry standards, you will know about the Initialization Vector (IV). In rough terms, the IV is a value added to the process that changes the cyphertext, so even if you encrypt two identical plaintexts with the same key, the corresponding cyphertext will change.



      The IV is the random data you are thinking about adding. It's already there.







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Aug 31 at 1:27

























      answered Aug 30 at 14:43









      ThoriumBR

      16.4k44060




      16.4k44060











      • Since OP says that he sees the same token generated, I guess it's not properly encrypted with an IV. In that case, maybe he should add it or change what he's using for encryption to something that does add it for him.
        – JoL
        Aug 30 at 17:42










      • When encrypting a large amount of data, the cost of storing or transmitting an IV with the encrypted data will be usually be small relative to the cost of storing or transmitting everything else. If the payload is small, however, the cost of the IV relative to the payload may be more significant.
        – supercat
        Aug 30 at 21:08










      • If you don't use an IV and the data is small and predictable, you will disclose your key. And as you have one single key on the server, losing that key means disaster...
        – ThoriumBR
        Aug 30 at 23:40
















      • Since OP says that he sees the same token generated, I guess it's not properly encrypted with an IV. In that case, maybe he should add it or change what he's using for encryption to something that does add it for him.
        – JoL
        Aug 30 at 17:42










      • When encrypting a large amount of data, the cost of storing or transmitting an IV with the encrypted data will be usually be small relative to the cost of storing or transmitting everything else. If the payload is small, however, the cost of the IV relative to the payload may be more significant.
        – supercat
        Aug 30 at 21:08










      • If you don't use an IV and the data is small and predictable, you will disclose your key. And as you have one single key on the server, losing that key means disaster...
        – ThoriumBR
        Aug 30 at 23:40















      Since OP says that he sees the same token generated, I guess it's not properly encrypted with an IV. In that case, maybe he should add it or change what he's using for encryption to something that does add it for him.
      – JoL
      Aug 30 at 17:42




      Since OP says that he sees the same token generated, I guess it's not properly encrypted with an IV. In that case, maybe he should add it or change what he's using for encryption to something that does add it for him.
      – JoL
      Aug 30 at 17:42












      When encrypting a large amount of data, the cost of storing or transmitting an IV with the encrypted data will be usually be small relative to the cost of storing or transmitting everything else. If the payload is small, however, the cost of the IV relative to the payload may be more significant.
      – supercat
      Aug 30 at 21:08




      When encrypting a large amount of data, the cost of storing or transmitting an IV with the encrypted data will be usually be small relative to the cost of storing or transmitting everything else. If the payload is small, however, the cost of the IV relative to the payload may be more significant.
      – supercat
      Aug 30 at 21:08












      If you don't use an IV and the data is small and predictable, you will disclose your key. And as you have one single key on the server, losing that key means disaster...
      – ThoriumBR
      Aug 30 at 23:40




      If you don't use an IV and the data is small and predictable, you will disclose your key. And as you have one single key on the server, losing that key means disaster...
      – ThoriumBR
      Aug 30 at 23:40












      up vote
      4
      down vote













      Let's try to break this down:



      Problem: replaying a token:




      Apart from allowing the same request to be replayed against the endpoint ad infinitum




      Usually auth tokens solve this problem by expiring the tokens: the encrypted data includes a datestamp (which has the side-effect of making each token unique) and the server will reject any token older than, say 15 minutes.



      Problem: breaking crypto:




      this makes it more likely that someone will be able to break the token encryption




      I'm not an expert, but it would seem to me that you should use a random IV for each encryption, and include the IV with the cipher text as part of the token. This would both solve the cryptanalysis problem you're alluding to, and have the side-effect of making your tokens unique. (if you're not using random IVs, then you probably have much bigger problems on your hands)



      Why not use a standard library to do this rather than going out of your depth to design your own encryption scheme? I would recommend JWT.




      Finally, as a public service I need to correct this: GUIDs ARE NOT HIGH-QUALITY RANDOMNESS.



      See Wikipedia/Universally_unique_identifier.



      UUIDs / GUIDs are designed to be unique, they make no attempt to be unpredictable. There are 5 standard ways to derive a UUID; 4 of them are some combination of MAC address + hostname + timestamp. Version 4 UUIDs are pure random, but because UUIDs / GUIDs generation needs to be fast and non-blocking, they use non-cryptographic random number generators.



      PLEASE DO NOT USE UUIDs / GUIDs AS A SOURCE OF CRYPTOGRAPHIC RANDOMNESS. Instead use /dev/random in unix, SecureRandomin java, or whatever the equivalent is in your OS / programming language






      share|improve this answer


















      • 2




        don't you mean /dev/urandom? devs shouldn't use /random for anything unless you are an expert making your own crypto system, and even then; don't roll your own crypto.
        – dandavis
        Aug 30 at 18:45







      • 3




        @dandavis uuuggggg I'm not getting into this debate again. They both have pros and cons. random is safer but may have performance issues, urandom is secure if your your system has been up for a while, is not an IoT device. etc. On most non-linux unixes /dev/random and /dev/urandom are symlinks to each other (ex. BSD, MacOS and iOS, Solaris (I think), AIX, etc). Personally I like FreeBSD's implementation better than linux's, but *shrug*. Basically: yes I know the difference, no I don't think they're significant enough to have yet another debate over.
        – Mike Ounsworth
        Aug 30 at 18:56







      • 1




        heh, no debate needed; i think your comment provides the context the answer missed...
        – dandavis
        Aug 30 at 19:02














      up vote
      4
      down vote













      Let's try to break this down:



      Problem: replaying a token:




      Apart from allowing the same request to be replayed against the endpoint ad infinitum




      Usually auth tokens solve this problem by expiring the tokens: the encrypted data includes a datestamp (which has the side-effect of making each token unique) and the server will reject any token older than, say 15 minutes.



      Problem: breaking crypto:




      this makes it more likely that someone will be able to break the token encryption




      I'm not an expert, but it would seem to me that you should use a random IV for each encryption, and include the IV with the cipher text as part of the token. This would both solve the cryptanalysis problem you're alluding to, and have the side-effect of making your tokens unique. (if you're not using random IVs, then you probably have much bigger problems on your hands)



      Why not use a standard library to do this rather than going out of your depth to design your own encryption scheme? I would recommend JWT.




      Finally, as a public service I need to correct this: GUIDs ARE NOT HIGH-QUALITY RANDOMNESS.



      See Wikipedia/Universally_unique_identifier.



      UUIDs / GUIDs are designed to be unique, they make no attempt to be unpredictable. There are 5 standard ways to derive a UUID; 4 of them are some combination of MAC address + hostname + timestamp. Version 4 UUIDs are pure random, but because UUIDs / GUIDs generation needs to be fast and non-blocking, they use non-cryptographic random number generators.



      PLEASE DO NOT USE UUIDs / GUIDs AS A SOURCE OF CRYPTOGRAPHIC RANDOMNESS. Instead use /dev/random in unix, SecureRandomin java, or whatever the equivalent is in your OS / programming language






      share|improve this answer


















      • 2




        don't you mean /dev/urandom? devs shouldn't use /random for anything unless you are an expert making your own crypto system, and even then; don't roll your own crypto.
        – dandavis
        Aug 30 at 18:45







      • 3




        @dandavis uuuggggg I'm not getting into this debate again. They both have pros and cons. random is safer but may have performance issues, urandom is secure if your your system has been up for a while, is not an IoT device. etc. On most non-linux unixes /dev/random and /dev/urandom are symlinks to each other (ex. BSD, MacOS and iOS, Solaris (I think), AIX, etc). Personally I like FreeBSD's implementation better than linux's, but *shrug*. Basically: yes I know the difference, no I don't think they're significant enough to have yet another debate over.
        – Mike Ounsworth
        Aug 30 at 18:56







      • 1




        heh, no debate needed; i think your comment provides the context the answer missed...
        – dandavis
        Aug 30 at 19:02












      up vote
      4
      down vote










      up vote
      4
      down vote









      Let's try to break this down:



      Problem: replaying a token:




      Apart from allowing the same request to be replayed against the endpoint ad infinitum




      Usually auth tokens solve this problem by expiring the tokens: the encrypted data includes a datestamp (which has the side-effect of making each token unique) and the server will reject any token older than, say 15 minutes.



      Problem: breaking crypto:




      this makes it more likely that someone will be able to break the token encryption




      I'm not an expert, but it would seem to me that you should use a random IV for each encryption, and include the IV with the cipher text as part of the token. This would both solve the cryptanalysis problem you're alluding to, and have the side-effect of making your tokens unique. (if you're not using random IVs, then you probably have much bigger problems on your hands)



      Why not use a standard library to do this rather than going out of your depth to design your own encryption scheme? I would recommend JWT.




      Finally, as a public service I need to correct this: GUIDs ARE NOT HIGH-QUALITY RANDOMNESS.



      See Wikipedia/Universally_unique_identifier.



      UUIDs / GUIDs are designed to be unique, they make no attempt to be unpredictable. There are 5 standard ways to derive a UUID; 4 of them are some combination of MAC address + hostname + timestamp. Version 4 UUIDs are pure random, but because UUIDs / GUIDs generation needs to be fast and non-blocking, they use non-cryptographic random number generators.



      PLEASE DO NOT USE UUIDs / GUIDs AS A SOURCE OF CRYPTOGRAPHIC RANDOMNESS. Instead use /dev/random in unix, SecureRandomin java, or whatever the equivalent is in your OS / programming language






      share|improve this answer














      Let's try to break this down:



      Problem: replaying a token:




      Apart from allowing the same request to be replayed against the endpoint ad infinitum




      Usually auth tokens solve this problem by expiring the tokens: the encrypted data includes a datestamp (which has the side-effect of making each token unique) and the server will reject any token older than, say 15 minutes.



      Problem: breaking crypto:




      this makes it more likely that someone will be able to break the token encryption




      I'm not an expert, but it would seem to me that you should use a random IV for each encryption, and include the IV with the cipher text as part of the token. This would both solve the cryptanalysis problem you're alluding to, and have the side-effect of making your tokens unique. (if you're not using random IVs, then you probably have much bigger problems on your hands)



      Why not use a standard library to do this rather than going out of your depth to design your own encryption scheme? I would recommend JWT.




      Finally, as a public service I need to correct this: GUIDs ARE NOT HIGH-QUALITY RANDOMNESS.



      See Wikipedia/Universally_unique_identifier.



      UUIDs / GUIDs are designed to be unique, they make no attempt to be unpredictable. There are 5 standard ways to derive a UUID; 4 of them are some combination of MAC address + hostname + timestamp. Version 4 UUIDs are pure random, but because UUIDs / GUIDs generation needs to be fast and non-blocking, they use non-cryptographic random number generators.



      PLEASE DO NOT USE UUIDs / GUIDs AS A SOURCE OF CRYPTOGRAPHIC RANDOMNESS. Instead use /dev/random in unix, SecureRandomin java, or whatever the equivalent is in your OS / programming language







      share|improve this answer














      share|improve this answer



      share|improve this answer








      edited Aug 30 at 14:56

























      answered Aug 30 at 14:48









      Mike Ounsworth

      35.3k1384127




      35.3k1384127







      • 2




        don't you mean /dev/urandom? devs shouldn't use /random for anything unless you are an expert making your own crypto system, and even then; don't roll your own crypto.
        – dandavis
        Aug 30 at 18:45







      • 3




        @dandavis uuuggggg I'm not getting into this debate again. They both have pros and cons. random is safer but may have performance issues, urandom is secure if your your system has been up for a while, is not an IoT device. etc. On most non-linux unixes /dev/random and /dev/urandom are symlinks to each other (ex. BSD, MacOS and iOS, Solaris (I think), AIX, etc). Personally I like FreeBSD's implementation better than linux's, but *shrug*. Basically: yes I know the difference, no I don't think they're significant enough to have yet another debate over.
        – Mike Ounsworth
        Aug 30 at 18:56







      • 1




        heh, no debate needed; i think your comment provides the context the answer missed...
        – dandavis
        Aug 30 at 19:02












      • 2




        don't you mean /dev/urandom? devs shouldn't use /random for anything unless you are an expert making your own crypto system, and even then; don't roll your own crypto.
        – dandavis
        Aug 30 at 18:45







      • 3




        @dandavis uuuggggg I'm not getting into this debate again. They both have pros and cons. random is safer but may have performance issues, urandom is secure if your your system has been up for a while, is not an IoT device. etc. On most non-linux unixes /dev/random and /dev/urandom are symlinks to each other (ex. BSD, MacOS and iOS, Solaris (I think), AIX, etc). Personally I like FreeBSD's implementation better than linux's, but *shrug*. Basically: yes I know the difference, no I don't think they're significant enough to have yet another debate over.
        – Mike Ounsworth
        Aug 30 at 18:56







      • 1




        heh, no debate needed; i think your comment provides the context the answer missed...
        – dandavis
        Aug 30 at 19:02







      2




      2




      don't you mean /dev/urandom? devs shouldn't use /random for anything unless you are an expert making your own crypto system, and even then; don't roll your own crypto.
      – dandavis
      Aug 30 at 18:45





      don't you mean /dev/urandom? devs shouldn't use /random for anything unless you are an expert making your own crypto system, and even then; don't roll your own crypto.
      – dandavis
      Aug 30 at 18:45





      3




      3




      @dandavis uuuggggg I'm not getting into this debate again. They both have pros and cons. random is safer but may have performance issues, urandom is secure if your your system has been up for a while, is not an IoT device. etc. On most non-linux unixes /dev/random and /dev/urandom are symlinks to each other (ex. BSD, MacOS and iOS, Solaris (I think), AIX, etc). Personally I like FreeBSD's implementation better than linux's, but *shrug*. Basically: yes I know the difference, no I don't think they're significant enough to have yet another debate over.
      – Mike Ounsworth
      Aug 30 at 18:56





      @dandavis uuuggggg I'm not getting into this debate again. They both have pros and cons. random is safer but may have performance issues, urandom is secure if your your system has been up for a while, is not an IoT device. etc. On most non-linux unixes /dev/random and /dev/urandom are symlinks to each other (ex. BSD, MacOS and iOS, Solaris (I think), AIX, etc). Personally I like FreeBSD's implementation better than linux's, but *shrug*. Basically: yes I know the difference, no I don't think they're significant enough to have yet another debate over.
      – Mike Ounsworth
      Aug 30 at 18:56





      1




      1




      heh, no debate needed; i think your comment provides the context the answer missed...
      – dandavis
      Aug 30 at 19:02




      heh, no debate needed; i think your comment provides the context the answer missed...
      – dandavis
      Aug 30 at 19:02










      up vote
      1
      down vote













      The solution that is used on my platform of choice is "encrypt/decrypt with managed IV (Initialization Vector)." What this means is that, upon encryption, the entire plain text is encrypted with a cryptographic secure IV, and then the IV is placed in base64-format before the beginning of the cipher text. Upon decryption, the IV is pulled off the front and used as the IV for the cipher text. This is all transparent to the developer. Note that it is perfectly safe to expose the IV, because decryption with the correct key but wrong IV will result in a failure condition. If your programming language has a similar feature, do use it; by having a random IV generated each time you encrypt something, you don't need to put any extra data in the plain text.






      share|improve this answer
























        up vote
        1
        down vote













        The solution that is used on my platform of choice is "encrypt/decrypt with managed IV (Initialization Vector)." What this means is that, upon encryption, the entire plain text is encrypted with a cryptographic secure IV, and then the IV is placed in base64-format before the beginning of the cipher text. Upon decryption, the IV is pulled off the front and used as the IV for the cipher text. This is all transparent to the developer. Note that it is perfectly safe to expose the IV, because decryption with the correct key but wrong IV will result in a failure condition. If your programming language has a similar feature, do use it; by having a random IV generated each time you encrypt something, you don't need to put any extra data in the plain text.






        share|improve this answer






















          up vote
          1
          down vote










          up vote
          1
          down vote









          The solution that is used on my platform of choice is "encrypt/decrypt with managed IV (Initialization Vector)." What this means is that, upon encryption, the entire plain text is encrypted with a cryptographic secure IV, and then the IV is placed in base64-format before the beginning of the cipher text. Upon decryption, the IV is pulled off the front and used as the IV for the cipher text. This is all transparent to the developer. Note that it is perfectly safe to expose the IV, because decryption with the correct key but wrong IV will result in a failure condition. If your programming language has a similar feature, do use it; by having a random IV generated each time you encrypt something, you don't need to put any extra data in the plain text.






          share|improve this answer












          The solution that is used on my platform of choice is "encrypt/decrypt with managed IV (Initialization Vector)." What this means is that, upon encryption, the entire plain text is encrypted with a cryptographic secure IV, and then the IV is placed in base64-format before the beginning of the cipher text. Upon decryption, the IV is pulled off the front and used as the IV for the cipher text. This is all transparent to the developer. Note that it is perfectly safe to expose the IV, because decryption with the correct key but wrong IV will result in a failure condition. If your programming language has a similar feature, do use it; by having a random IV generated each time you encrypt something, you don't need to put any extra data in the plain text.







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Aug 30 at 18:01









          phyrfox

          3,8191120




          3,8191120




















              up vote
              0
              down vote













              To me, this looks like an XY Problem.



              The best way to protect a secret is not to tell anyone the secret. The token is generated server-side. The server already knows the data. And then you replay the token to the server, which contains only data the server already has. That is completely unnecessary.



              Other answers have pointed out the quick, immediate fix for your encryption problem by using encryption with IVs. But the better solution would be to make this superfluous.




              Server builds up token using various values, encrypts it (via an industry-standard algorithm, nothing homegrown) using a key only the server knows, and returns it as part of the page data




              Instead of encrypting those values, save them in a database. You can potentially, if you really must, still encrypt those values and then save them. But there is absolutely no need for these values to ever leave the server, even in encrypted form.
              Then generate a truly random token (with a CSPRNG), and use that as a lookup-key. Send this token to the client.




              Token is embedded into link on page




              Use the random token you just generated for that.




              When client clicks that link, token is sent to server, decrypted and parsed and the values used to determine what to do




              Instead of decrypting and parsing the values, you use the token to look them up in the database. Done. If you only stored the data encrypted, you still need to decrypt it, of course.



              This also works if you have multiple servers. If the token is generated on Server A and send to Server B, have Server B use a secure connection to Server A and request the data via the token from Server A. In this scenario, too, the data is never sent to the client.




              This is done because we need certain bits of information to be sent from the client to the server, but we don't want to leak those bits of information to the client because they would reveal details of the server's inner workings




              Internal state should never leak from an implementation. This is already a code smell and a good hint that your architecture is flawed.






              share|improve this answer


























                up vote
                0
                down vote













                To me, this looks like an XY Problem.



                The best way to protect a secret is not to tell anyone the secret. The token is generated server-side. The server already knows the data. And then you replay the token to the server, which contains only data the server already has. That is completely unnecessary.



                Other answers have pointed out the quick, immediate fix for your encryption problem by using encryption with IVs. But the better solution would be to make this superfluous.




                Server builds up token using various values, encrypts it (via an industry-standard algorithm, nothing homegrown) using a key only the server knows, and returns it as part of the page data




                Instead of encrypting those values, save them in a database. You can potentially, if you really must, still encrypt those values and then save them. But there is absolutely no need for these values to ever leave the server, even in encrypted form.
                Then generate a truly random token (with a CSPRNG), and use that as a lookup-key. Send this token to the client.




                Token is embedded into link on page




                Use the random token you just generated for that.




                When client clicks that link, token is sent to server, decrypted and parsed and the values used to determine what to do




                Instead of decrypting and parsing the values, you use the token to look them up in the database. Done. If you only stored the data encrypted, you still need to decrypt it, of course.



                This also works if you have multiple servers. If the token is generated on Server A and send to Server B, have Server B use a secure connection to Server A and request the data via the token from Server A. In this scenario, too, the data is never sent to the client.




                This is done because we need certain bits of information to be sent from the client to the server, but we don't want to leak those bits of information to the client because they would reveal details of the server's inner workings




                Internal state should never leak from an implementation. This is already a code smell and a good hint that your architecture is flawed.






                share|improve this answer
























                  up vote
                  0
                  down vote










                  up vote
                  0
                  down vote









                  To me, this looks like an XY Problem.



                  The best way to protect a secret is not to tell anyone the secret. The token is generated server-side. The server already knows the data. And then you replay the token to the server, which contains only data the server already has. That is completely unnecessary.



                  Other answers have pointed out the quick, immediate fix for your encryption problem by using encryption with IVs. But the better solution would be to make this superfluous.




                  Server builds up token using various values, encrypts it (via an industry-standard algorithm, nothing homegrown) using a key only the server knows, and returns it as part of the page data




                  Instead of encrypting those values, save them in a database. You can potentially, if you really must, still encrypt those values and then save them. But there is absolutely no need for these values to ever leave the server, even in encrypted form.
                  Then generate a truly random token (with a CSPRNG), and use that as a lookup-key. Send this token to the client.




                  Token is embedded into link on page




                  Use the random token you just generated for that.




                  When client clicks that link, token is sent to server, decrypted and parsed and the values used to determine what to do




                  Instead of decrypting and parsing the values, you use the token to look them up in the database. Done. If you only stored the data encrypted, you still need to decrypt it, of course.



                  This also works if you have multiple servers. If the token is generated on Server A and send to Server B, have Server B use a secure connection to Server A and request the data via the token from Server A. In this scenario, too, the data is never sent to the client.




                  This is done because we need certain bits of information to be sent from the client to the server, but we don't want to leak those bits of information to the client because they would reveal details of the server's inner workings




                  Internal state should never leak from an implementation. This is already a code smell and a good hint that your architecture is flawed.






                  share|improve this answer














                  To me, this looks like an XY Problem.



                  The best way to protect a secret is not to tell anyone the secret. The token is generated server-side. The server already knows the data. And then you replay the token to the server, which contains only data the server already has. That is completely unnecessary.



                  Other answers have pointed out the quick, immediate fix for your encryption problem by using encryption with IVs. But the better solution would be to make this superfluous.




                  Server builds up token using various values, encrypts it (via an industry-standard algorithm, nothing homegrown) using a key only the server knows, and returns it as part of the page data




                  Instead of encrypting those values, save them in a database. You can potentially, if you really must, still encrypt those values and then save them. But there is absolutely no need for these values to ever leave the server, even in encrypted form.
                  Then generate a truly random token (with a CSPRNG), and use that as a lookup-key. Send this token to the client.




                  Token is embedded into link on page




                  Use the random token you just generated for that.




                  When client clicks that link, token is sent to server, decrypted and parsed and the values used to determine what to do




                  Instead of decrypting and parsing the values, you use the token to look them up in the database. Done. If you only stored the data encrypted, you still need to decrypt it, of course.



                  This also works if you have multiple servers. If the token is generated on Server A and send to Server B, have Server B use a secure connection to Server A and request the data via the token from Server A. In this scenario, too, the data is never sent to the client.




                  This is done because we need certain bits of information to be sent from the client to the server, but we don't want to leak those bits of information to the client because they would reveal details of the server's inner workings




                  Internal state should never leak from an implementation. This is already a code smell and a good hint that your architecture is flawed.







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Sep 1 at 9:31

























                  answered Sep 1 at 7:53









                  Polygnome

                  1015




                  1015



























                       

                      draft saved


                      draft discarded















































                       


                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function ()
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsecurity.stackexchange.com%2fquestions%2f192731%2fdoes-appending-randomness-to-a-token-before-encrypting-it-make-it-more-secure%23new-answer', 'question_page');

                      );

                      Post as a guest













































































                      Comments

                      Popular posts from this blog

                      What does second last employer means? [closed]

                      List of Gilmore Girls characters

                      Confectionery