• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Tim Cooke
  • Campbell Ritchie
  • paul wheaton
  • Ron McLeod
  • Devaka Cooray
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Paul Clapham
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Piet Souris
Bartenders:

Understanding Encrypt-Decrypt of txt file by DES

 
Ranch Hand
Posts: 630
Android Java Linux
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
I try to understand how Encryption-Decryption done by java.
I create 1 text file named 'Hello.txt' & in that only one line i kept 'Hello World'.
I use 'DES/ECB/PKCS5Padding' as Cipher.
For testing purpose i kept 2 different secret keys, one for Encryption & other for Decryption.
I thought when I decrypt contain which encrypted by differently, i will got error/exception. but i got success.
For understand how key works or how algorithm works, i read wikipedia, & other references got by Google.

My questions:-
1. How 2 different keys works in DES Encryption-Decryption?
2. If i want to use more secure Algorithm for txt file(for example hello.txt) with secret key String which contain 26 characters, which one should i use from below & how:-

  • AES/CBC/NoPadding (128)
    AES/CBC/PKCS5Padding (128)
    AES/ECB/NoPadding (128)
    AES/ECB/PKCS5Padding (128)
    DES/CBC/NoPadding (56)
    DES/CBC/PKCS5Padding (56)
    DES/ECB/NoPadding (56)
    DES/ECB/PKCS5Padding (56)
    DESede/CBC/NoPadding (168)
    DESede/CBC/PKCS5Padding (168)
    DESede/ECB/NoPadding (168)
    DESede/ECB/PKCS5Padding (168)
    RSA/ECB/PKCS1Padding (1024, 2048)
    RSA/ECB/OAEPWithSHA-1AndMGF1Padding (1024, 2048)
    RSA/ECB/OAEPWithSHA-256AndMGF1Padding (1024, 2048)

  • 3. In jdk1.8.0_51, i cant find SecretKeySpec.java when i used Eclipse's Open Declaration & attached src.zip which i found in JDK folder in Windows pc which used Oracle JDK, But i can find in Linux pc which use OpenJDK! Why this difference? How can i see source of SecretKeySpec.java or other files which should be in 'javax.crypto' in windows PC with Oracle JDK?

    Here for reference program which i wrote with help of Google.
    Program as below:-

    When above code runs i got result as below:-

    When i use 2nd key with 02, i got Exception as below:-

    Help me.
     
    Ranch Hand
    Posts: 954
    4
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Problem is with your keys. I suppose it is calculating same values for your given keys. Try to use different keys.

    I used different keys and it is giving expected result now:




     
    Tushar Goel
    Ranch Hand
    Posts: 954
    4
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Also i see 1 more issue, you have used same "file" instance for both input and output stream(Line 64-66 and 40-42). You should use different instance.
     
    Mandar Khire
    Ranch Hand
    Posts: 630
    Android Java Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks Tushar Goel,

    Also i see 1 more issue, you have used same "file" instance for both input and output stream(Line 64-66 and 40-42). You should use different instance.


    I change it accordingly my code.

    Problem is with your keys. I suppose it is calculating same values for your given keys. Try to use different keys.


    I used different keys & got encryption - problem in decryption.
    But my question is why i not got error when

    Why these two strings not different in prospect of SecretKeySpec or Cipher?
    For reference here you find my new code which i modified :-
     
    author
    Posts: 23959
    142
    jQuery Eclipse IDE Firefox Browser VI Editor C++ Chrome Java Linux Windows
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Mandar Khire wrote:
    1. How 2 different keys works in DES Encryption-Decryption?



    With DES, you can actually "decrypt" plain text and you will get a cipher text. This text is not readable, until you "encrypt" it back to plain text.

    So, when you encrypt with one key and then "decrypt" with a second key, you are effectively encrypting twice. To get back the original plain text, you will need to encrypt with the second key, and then decrypt with the first key (reversing the process).

    Henry
     
    Mandar Khire
    Ranch Hand
    Posts: 630
    Android Java Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks Henry Wong,
    As you wrote

    With DES, you can actually "decrypt" plain text and you will get a cipher text. This text is not readable, until you "encrypt" it back to plain text.


    When i use Encryption key

    I got result as below in 'hello1.txt


    & to this file i decrypt it by using key

    I got result as same as original file!

    I know that

    So, when you encrypt with one key and then "decrypt" with a second key, you are effectively encrypting twice. To get back the original plain text, you will need to encrypt with the second key, and then decrypt with the first key (reversing the process).



    My question is why not i get exceptions when i using different keys.
    I tried with
    Then i got exceptions which is valid.

    1 thing i know that(I read Wikipedia)

    In symmetric-key schemes,[3] the encryption and decryption keys are the same. Communicating parties must have the same key before they can achieve secure communication.


    In DES

    The Data Encryption Standard was once a predominant symmetric-key algorithm for the encryption of electronic data.


    &

    Controversies arose out of classified design elements, a relatively short key length of the symmetric-key block cipher design, and the involvement of the NSA, nourishing suspicions about a backdoor.

    .
     
    Bartender
    Posts: 15741
    368
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    What you're seeing is because you're using a really crappy algorithm (DES) with a really crappy block mode (ECB) and two keys that are very similar.

    This will probably fail if you use an algorithm such as AES in CTR mode. When you do this, you also need to output the IV of the encryption phase, and pass that in an IvParameterSpec to the decryption Cipher.
     
    Stephan van Hulst
    Bartender
    Posts: 15741
    368
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    For proper message encryption you will want to use an AEAD algorithm, such as AES-GCM.
     
    Tushar Goel
    Ranch Hand
    Posts: 954
    4
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    or CBC mode with PKCS5Padding
     
    Stephan van Hulst
    Bartender
    Posts: 15741
    368
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    No. Authentication should be part of any encryption, and AES in CBC mode does not provide authentication without a MAC.

    Unless you're gonna create some fancy secure protocol (which most of us probably never will), don't use low level crypto like AES-CBC. Instead, use AEAD algorithms like AES-GCM or AES-CCM.

    This is important: Encryption and authentication are closely related. Don't encrypt without authentication!
     
    Mandar Khire
    Ranch Hand
    Posts: 630
    Android Java Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks Stephan van Hulst,

    For proper message encryption you will want to use an AEAD algorithm, such as AES-GCM.


    I change my code for 'AES'
    Code is as below:-

    By this i got exception when i used 2 different keys.

    This is important: Encryption and authentication are closely related. Don't encrypt without authentication!


    What is authentication in above examples? Did i miss it?

    for second question in first post:-
    Which Algorithm should i use when i want to use key length is 26 characters?
    example
     
    Stephan van Hulst
    Bartender
    Posts: 15741
    368
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Mandar Khire wrote:I change my code for 'AES'
    [...]
    What is authentication in above examples? Did i miss it?


    Yes, you're not authenticating the ciphertext. You can do this with a HMAC or preferably with an AEAD algorithm. The transformation would be "AES/GCM/NoPadding".

    Which Algorithm should i use when i want to use key length is 26 characters?


    You're directly using your passwords as key material. This is bad. You should use a key factory that transforms passwords to secret keys. First, use a PBEKeySpec to generate the key material, and then transform that key material to an AES key. You should also never use String to store passwords. Use char[] or byte[] arrays.

    Another problem is that you're not saving the initialization vector with your encrypted message. Without the IV, you can not decrypt messages on the other side.

    Here's a complete example:
     
    Stephan van Hulst
    Bartender
    Posts: 15741
    368
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Technically, this example can be considered insecure because I'm using String for the plainText, which causes sensitive data to remain in memory for longer than needed. Sensitive plain text, just like passwords, should be passed as byte[] or char[] arrays.
     
    Mandar Khire
    Ranch Hand
    Posts: 630
    Android Java Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks Stephan van Hulst,

    You're directly using your passwords as key material. This is bad. You should use a key factory that transforms passwords to secret keys. First, use a PBEKeySpec to generate the key material, and then transform that key material to an AES key. You should also never use String to store passwords. Use char[] or byte[] arrays.

    .
    This is not password but it look like password, i some how get HDD productkey & UUID.
    Some how i use 'message digest algorithm' with those two & generate long string then convert it as given string.
    So it look like Password.
    But for each different pc, it is different. Or we can say with different HDD, it different.
    Its compulsory for me to use it.
    By reading given example i try to Encrypt & decrypt txt file. but i failed.
    Here is my source code

    but i got Exception as below:-


    Can i get help to solve this?
     
    Stephan van Hulst
    Bartender
    Posts: 15741
    368
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    That's logical, because you're generating a new key for each operation. You need to generate a key only once, and reuse that key if you want to decrypt any message encrypted with that key. Generating a new key with the same key material won't work.

    Stop coding, and figure out what your requirements are.

    - Who is going to encrypt?
    - Who is going to decrypt?
    - How are you going to share the secret between these two parties? (Remember, a secret is secret, so don't use predictable data such as hardware IDs.)
    - How are you going to store the secret between sessions? (Key stores or enter password every time?)

    A few more things:

    - There is no use in calling toCharArray() on a String containing sensitive data. Once the sensitive data is in the form of a String, you have already lost.
    - It doesn't matter whether it's an UUID or user input, a variable amount of characters should be considered a password, and an actual secret key should be derived from that.
    - You are not using the IV properly. THIS IS A HUGE SECURITY FLAW. The IV should be unique for every encryption operation.

    I suggest you read up on block ciphers, initialization vectors, symmetric keys, message authentication and good cryptography practices in general. If you don't understand why you're writing a particular line of code, you're probably breaking security.
     
    Mandar Khire
    Ranch Hand
    Posts: 630
    Android Java Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks Stephan van Hulst,
    I got my mistake & resolve it as

    That's logical, because you're generating a new key for each operation. You need to generate a key only once, and reuse that key if you want to decrypt any message encrypted with that key.



    - Who is going to encrypt?
    - Who is going to decrypt?
    - How are you going to share the secret between these two parties? (Remember, a secret is secret, so don't use predictable data such as hardware IDs.)
    - How are you going to store the secret between sessions? (Key stores or enter password every time?)


    Yes, i will rethink about these questions.

    Once the sensitive data is in the form of a String, you have already lost.
    - It doesn't matter whether it's an UUID or user input, a variable amount of characters should be considered a password, and an actual secret key should be derived from that.


    I just give you small hint of my logic (HDD etc), other 4 to 5 factors i used for generate sensitive data.
    Then I Encrypt my sensitive data with SHA-512. It generate 128 character string, from it i just use 24 characters.
    (These 26 also i pick with one another logic which randomly chose it. out of 128.)
    So as per my requirements, i think that i use more complexity for picking string for security key. Now from your example i used more complexity to generate 'Security key'.
    This also not sufficient to secure a 'security key'?

    - You are not using the IV properly. THIS IS A HUGE SECURITY FLAW. The IV should be unique for every encryption operation.


    I will work on it.

    I suggest you read up on block ciphers, initialization vectors, symmetric keys, message authentication and good cryptography practices in general. If you don't understand why you're writing a particular line of code, you're probably breaking security.


    I definitely study about those things.

    I found link which shows CipherInputStream for AEAD modes is insecure in JDK7 (GCM, EAX, etc.)
    If this is true, then which other Algorithm i should use for more secure my 'hello.txt'.
    waiting for expert comments.

    Here i give working code:-
     
    Stephan van Hulst
    Bartender
    Posts: 15741
    368
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Mandar Khire wrote:I just give you small hint of my logic (HDD etc), other 4 to 5 factors i used for generate sensitive data.
    Then I Encrypt my sensitive data with SHA-512. It generate 128 character string, from it i just use 24 characters.
    (These 26 also i pick with one another logic which randomly chose it. out of 128.)
    So as per my requirements, i think that i use more complexity for picking string for security key. Now from your example i used more complexity to generate 'Security key'.
    This also not sufficient to secure a 'security key'?


    I really don't understand this. Either generate a completely random secret key once and distribute it to every trusted application (In a key store!!!), or derive a key from a password. Why are you even using hardware IDs and other factors? This serves absolutely no purpose other than making the password less secure. Your custom hashing and byte juggling is probably cryptographically WEAK. This is exactly why you should derive a secret key using a SecretKeyFactory instead. Don't mess with primitives like SHA-512!

    I found link which shows CipherInputStream for AEAD modes is insecure in JDK7 (GCM, EAX, etc.)
    If this is true, then which other Algorithm i should use for more secure my 'hello.txt'.


    I believe this issue has been fixed in more recent versions. If it hasn't, stop using CipherInputStream, and just use Cipher directly. You're not using CipherInputStream like a stream anyway.

    - Why is iv static?
    - Why is tagLength static?
    - Why are you using securitykey2? Symmetric algorithms require one key.
    - Why are you storing the password (Yes, you're using "D0A81F-E11293-4B5D29-BCEC1" as a password) as a String?
    - Why are you using String for paths, and not Path?
    - Why are you constructing a Message without using it?
    - Why are you storing the key in the message (THIS IS BAAAAD).
    - Why are you using buffers if you're working with streams?
    - Why are you not using try-with-resources for your streams?

    If you want to encrypt an entire file, you need to think about the file format of your encrypted file. AES-GCM will only store the cipher text and the authentication tag. You still need to store the initialization vector, and possibly other header information (like the algorithm used, the algorithm parameters, etc.)
     
    Mandar Khire
    Ranch Hand
    Posts: 630
    Android Java Linux
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator
    Thanks Stephan van Hulst,

    I really don't understand this....


    Actually my actual work done by very first program with DES though it very bad. But for educating myself i try to do RnD & improving myself.
    Fact is, the String which i share with you, is just part of one logic which use in Licensing of StandAlone desktop application.
    Using this string which actually not use as String actually in program i should do encrypt & decrypt some files in same application.

    Why are you even using hardware IDs and other factors?


    I dont find any other way to generate Product key for standalone java app.
    User of my app is not that much of Educated to crack things like professional hackers.(Might be.)
    But i know...what i am doing...I cant fool myself by giving very bad logic.

    My aim is
    example PC A has app & it will has product key by that i will give License key to user. Now if i can store that info in some file, i should encrypt it & hide it.
    Whenever i have to cross verify license, i will decrypt that file, fetch data & cross verify it.
    Now if i copy this hidden & encrypted file, paste it into PC B, by thought of cracking license, it should give me error. So i use Hardware based some key.
    I not depend on 1 hardware, i take 4-5 things which very essential for pc.
    Each give me some data & each data i encrypt with some logic with different algorithm. So i try to make complex to get license key.

    1 more thing PC A & B or other may be Linux(Centos/Ubuntu/Fedora) or Windows(XP/7/8).
    I think this explanation is quite sufficient to understand why i use that string which look like password!

    Don't mess with primitives like SHA-512!


    Why? I dont understand it!

    If it hasn't, stop using CipherInputStream, and just use Cipher directly. You're not using CipherInputStream like a stream anyway.


    I will definitely try this.

    Why is iv static?
    - Why is tagLength static?
    - Why are you using securitykey2? Symmetric algorithms require one key.
    - Why are you storing the password (Yes, you're using "D0A81F-E11293-4B5D29-BCEC1" as a password) as a String?
    - Why are you using String for paths, and not Path?
    - Why are you constructing a Message without using it?
    - Why are you storing the key in the message (THIS IS BAAAAD).
    - Why are you using buffers if you're working with streams?
    - Why are you not using try-with-resources for your streams?


    Because i dont know how to improve my Hello (Cryptography)world code. I will defiantly work on it.

    f you want to encrypt an entire file, you need to think about the file format of your encrypted file.


    File format means .txt or .en or .den ? or something else?

    AES-GCM will only store the cipher text and the authentication tag. You still need to store the initialization vector, and possibly other header information (like the algorithm used, the algorithm parameters, etc.)


    Can i get expert explanation about this?
     
    Stephan van Hulst
    Bartender
    Posts: 15741
    368
    • Mark post as helpful
    • send pies
      Number of slices to send:
      Optional 'thank-you' note:
    • Quote
    • Report post to moderator

    Mandar Khire wrote:My aim is example PC A has app & it will has product key by that i will give License key to user. Now if i can store that info in some file, i should encrypt it & hide it.
    Whenever i have to cross verify license, i will decrypt that file, fetch data & cross verify it.
    Now if i copy this hidden & encrypted file, paste it into PC B, by thought of cracking license, it should give me error. So i use Hardware based some key.
    I not depend on 1 hardware, i take 4-5 things which very essential for pc.
    Each give me some data & each data i encrypt with some logic with different algorithm. So i try to make complex to get license key.


    You don't need to encrypt anything. All you need to do is create a license file that has a digital signature authenticating the contents of the license. You can store the hardware id and other factors in plain text, add a signature, and when the application starts, crosscheck the contents of the file with the device that the app is running on, and verify the digital signature. You don't need to hide anything at all.

    Don't mess with primitives like SHA-512!


    You shouldn't be using SHA-512 in an encryption algorithm, because high-level encryption algorithms already exist. By using SHA-512 (which is a hashing algorithm) to create your own algorithm, you're reinventing the wheel, and in crypto, that's a very bad idea.

    f you want to encrypt an entire file, you need to think about the file format of your encrypted file.


    This means how you're going to lay out the information you want to store in the file. You can have your custom file format. You can't just put the cipher text into a file and then decrypt it again later without extra information.

    AES-GCM will only store the cipher text and the authentication tag. You still need to store the initialization vector, and possibly other header information (like the algorithm used, the algorithm parameters, etc.)


    So let's say you encrypted some plain text and stored the cipher text. How are you going to decrypt it? You can't just enter the key and hope for the best. You need to understand that AES-GCM requires the same initialization vector you used to encrypt with. If you don't store that, how are you going to get it? To understand this, you really need to read how block cipher encryption modes work.
     
    Don't get me started about those stupid light bulbs.
    reply
      Bookmark Topic Watch Topic
    • New Topic