openssl_encrypt AES encrypt with out vector



.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








0















I need a token to access some source. The source provider gave me a java example that show me how to create it. Here is how it encrypt text:



private static final String ALGO = "AES"; 
public static String encrypt(byte keyValue, String token_text) throws Exception
Key key = new SecretKeySpec(keyValue, ALGO);
Cipher c = Cipher.getInstance(ALGO);
c.init(Cipher.ENCRYPT_MODE, key);

byte bytes = c.doFinal(token_text.getBytes());
byte buf = Base64.encodeBase64(bytes);

return new String(buf);



I wish to translate this pice of java program to php.So, here is my code:



public static function generate_token($token_text, $key) 
$iv = self::hex_to_str("00000000000000000000000000000000");
$token = openssl_encrypt($token_text, "AES-128-CBC", $key, 0, $iv);
return $token;


private static function hex_to_str($hex)

$string='';
for ($i=0; $i < strlen($hex)-1; $i+=2)

$string .= chr(hexdec($hex[$i].$hex[$i+1]));

return $string;



But I can't get same result. I searched around. It looks like cipher.init called without vector. If i do the same thing to openssl_encrypt, it will gave me an error:



openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended


Some one said the default vector for Cipher is 0. I tried so, still can't get the same result, but very close:



java: v8GhW0lu8DzNyqsfQTg4g7H6pwXCAAgy9vqFdz5OmXY=



php : v8GhW0lu8DzNyqsfQTg4g6If77f+8YVCcq8VcQGNe68=



I am stuck here for a whole day. I would be very grateful if anyone can help.



# java -version
openjdk version "1.8.0_101"
OpenJDK Runtime Environment (build 1.8.0_101-b13)
OpenJDK 64-Bit Server VM (build 25.101-b13, mixed mode)

# php -v
PHP 5.6.24 (cli) (built: Jul 21 2016 07:42:08)
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies









share|improve this question




























    0















    I need a token to access some source. The source provider gave me a java example that show me how to create it. Here is how it encrypt text:



    private static final String ALGO = "AES"; 
    public static String encrypt(byte keyValue, String token_text) throws Exception
    Key key = new SecretKeySpec(keyValue, ALGO);
    Cipher c = Cipher.getInstance(ALGO);
    c.init(Cipher.ENCRYPT_MODE, key);

    byte bytes = c.doFinal(token_text.getBytes());
    byte buf = Base64.encodeBase64(bytes);

    return new String(buf);



    I wish to translate this pice of java program to php.So, here is my code:



    public static function generate_token($token_text, $key) 
    $iv = self::hex_to_str("00000000000000000000000000000000");
    $token = openssl_encrypt($token_text, "AES-128-CBC", $key, 0, $iv);
    return $token;


    private static function hex_to_str($hex)

    $string='';
    for ($i=0; $i < strlen($hex)-1; $i+=2)

    $string .= chr(hexdec($hex[$i].$hex[$i+1]));

    return $string;



    But I can't get same result. I searched around. It looks like cipher.init called without vector. If i do the same thing to openssl_encrypt, it will gave me an error:



    openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended


    Some one said the default vector for Cipher is 0. I tried so, still can't get the same result, but very close:



    java: v8GhW0lu8DzNyqsfQTg4g7H6pwXCAAgy9vqFdz5OmXY=



    php : v8GhW0lu8DzNyqsfQTg4g6If77f+8YVCcq8VcQGNe68=



    I am stuck here for a whole day. I would be very grateful if anyone can help.



    # java -version
    openjdk version "1.8.0_101"
    OpenJDK Runtime Environment (build 1.8.0_101-b13)
    OpenJDK 64-Bit Server VM (build 25.101-b13, mixed mode)

    # php -v
    PHP 5.6.24 (cli) (built: Jul 21 2016 07:42:08)
    Copyright (c) 1997-2016 The PHP Group
    Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies









    share|improve this question
























      0












      0








      0








      I need a token to access some source. The source provider gave me a java example that show me how to create it. Here is how it encrypt text:



      private static final String ALGO = "AES"; 
      public static String encrypt(byte keyValue, String token_text) throws Exception
      Key key = new SecretKeySpec(keyValue, ALGO);
      Cipher c = Cipher.getInstance(ALGO);
      c.init(Cipher.ENCRYPT_MODE, key);

      byte bytes = c.doFinal(token_text.getBytes());
      byte buf = Base64.encodeBase64(bytes);

      return new String(buf);



      I wish to translate this pice of java program to php.So, here is my code:



      public static function generate_token($token_text, $key) 
      $iv = self::hex_to_str("00000000000000000000000000000000");
      $token = openssl_encrypt($token_text, "AES-128-CBC", $key, 0, $iv);
      return $token;


      private static function hex_to_str($hex)

      $string='';
      for ($i=0; $i < strlen($hex)-1; $i+=2)

      $string .= chr(hexdec($hex[$i].$hex[$i+1]));

      return $string;



      But I can't get same result. I searched around. It looks like cipher.init called without vector. If i do the same thing to openssl_encrypt, it will gave me an error:



      openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended


      Some one said the default vector for Cipher is 0. I tried so, still can't get the same result, but very close:



      java: v8GhW0lu8DzNyqsfQTg4g7H6pwXCAAgy9vqFdz5OmXY=



      php : v8GhW0lu8DzNyqsfQTg4g6If77f+8YVCcq8VcQGNe68=



      I am stuck here for a whole day. I would be very grateful if anyone can help.



      # java -version
      openjdk version "1.8.0_101"
      OpenJDK Runtime Environment (build 1.8.0_101-b13)
      OpenJDK 64-Bit Server VM (build 25.101-b13, mixed mode)

      # php -v
      PHP 5.6.24 (cli) (built: Jul 21 2016 07:42:08)
      Copyright (c) 1997-2016 The PHP Group
      Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies









      share|improve this question














      I need a token to access some source. The source provider gave me a java example that show me how to create it. Here is how it encrypt text:



      private static final String ALGO = "AES"; 
      public static String encrypt(byte keyValue, String token_text) throws Exception
      Key key = new SecretKeySpec(keyValue, ALGO);
      Cipher c = Cipher.getInstance(ALGO);
      c.init(Cipher.ENCRYPT_MODE, key);

      byte bytes = c.doFinal(token_text.getBytes());
      byte buf = Base64.encodeBase64(bytes);

      return new String(buf);



      I wish to translate this pice of java program to php.So, here is my code:



      public static function generate_token($token_text, $key) 
      $iv = self::hex_to_str("00000000000000000000000000000000");
      $token = openssl_encrypt($token_text, "AES-128-CBC", $key, 0, $iv);
      return $token;


      private static function hex_to_str($hex)

      $string='';
      for ($i=0; $i < strlen($hex)-1; $i+=2)

      $string .= chr(hexdec($hex[$i].$hex[$i+1]));

      return $string;



      But I can't get same result. I searched around. It looks like cipher.init called without vector. If i do the same thing to openssl_encrypt, it will gave me an error:



      openssl_encrypt(): Using an empty Initialization Vector (iv) is potentially insecure and not recommended


      Some one said the default vector for Cipher is 0. I tried so, still can't get the same result, but very close:



      java: v8GhW0lu8DzNyqsfQTg4g7H6pwXCAAgy9vqFdz5OmXY=



      php : v8GhW0lu8DzNyqsfQTg4g6If77f+8YVCcq8VcQGNe68=



      I am stuck here for a whole day. I would be very grateful if anyone can help.



      # java -version
      openjdk version "1.8.0_101"
      OpenJDK Runtime Environment (build 1.8.0_101-b13)
      OpenJDK 64-Bit Server VM (build 25.101-b13, mixed mode)

      # php -v
      PHP 5.6.24 (cli) (built: Jul 21 2016 07:42:08)
      Copyright (c) 1997-2016 The PHP Group
      Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies






      java php aes






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 16 '18 at 14:26









      crazyjincrazyjin

      516




      516






















          1 Answer
          1






          active

          oldest

          votes


















          2














          Under the assumption that the Java side uses the SunJCE-Provider the default mode is the ECB-mode and the default padding is the PKCS5Padding i.e. Cipher.getInstance("AES") is identical to Cipher.getInstance("AES/ECB/PKCS5Padding") see e.g. https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#ciphertrans.



          The ECB-mode doesn't use an IV. Thus, you have to replace in your PHP generate_token-method



          $iv = self::hex_to_str("00000000000000000000000000000000");
          $token = openssl_encrypt($token_text, "AES-128-CBC", $key, 0, $iv);


          with



          $token = openssl_encrypt($token_text, "AES-128-ECB", $key, 0);


          Example:



          encrypt("This is the key!".getBytes(), "This is a plain text that needs to be encrypted...");


          provides



          fLSh/HoQkrsIVBtZJVnuIRqcz4ztUBDkDG9Pi3xe49Q9hh9zDzWZDRHEO70ixfLf2WbWYSeDOQ/ONFTWHW9i0Q==


          which is identical to the result of the PHP code (for the same key and plain text).



          Generally, the ECB-mode is not secure if you have more than one block (from your examples I infer that your token consists of at least two blocks). Then, a better choice would be the CBC- or GCM-mode, see e.g. https://crypto.stackexchange.com/questions/20941/why-shouldnt-i-use-ecb-encryption and https://security.stackexchange.com/questions/6500/aes-ecb-mode-for-single-block-random-data-encryption. But since the Java encrypt-method seems to be your reference there is probably no way to change it.



          EDIT:



          The Java cipher-class determines automatically with the keysize if AES-128, AES-192 or AES-256 must be used. Therefore, you also have to know the size of the key in the context of the Java code. If the keysize is 16 byte then the choice of AES-128-ECB is correct, otherwise you have to adjust your PHP code accordingly (e.g. AES-192-ECB or AES-256-ECB for a 24 byte or a 32 byte keysize, respectively).






          share|improve this answer

























          • Yes! AES-128-ECB! Thank you!! You just saved my life. I tried every method list in php.net/manual/en/function.openssl-get-cipher-methods.php. But did not notice there are more methods and did not call openssl_get_cipher_methods by my self. What big mistake. Thank you, again.

            – crazyjin
            Nov 18 '18 at 9:39











          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53339751%2fopenssl-encrypt-aes-encrypt-with-out-vector%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









          2














          Under the assumption that the Java side uses the SunJCE-Provider the default mode is the ECB-mode and the default padding is the PKCS5Padding i.e. Cipher.getInstance("AES") is identical to Cipher.getInstance("AES/ECB/PKCS5Padding") see e.g. https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#ciphertrans.



          The ECB-mode doesn't use an IV. Thus, you have to replace in your PHP generate_token-method



          $iv = self::hex_to_str("00000000000000000000000000000000");
          $token = openssl_encrypt($token_text, "AES-128-CBC", $key, 0, $iv);


          with



          $token = openssl_encrypt($token_text, "AES-128-ECB", $key, 0);


          Example:



          encrypt("This is the key!".getBytes(), "This is a plain text that needs to be encrypted...");


          provides



          fLSh/HoQkrsIVBtZJVnuIRqcz4ztUBDkDG9Pi3xe49Q9hh9zDzWZDRHEO70ixfLf2WbWYSeDOQ/ONFTWHW9i0Q==


          which is identical to the result of the PHP code (for the same key and plain text).



          Generally, the ECB-mode is not secure if you have more than one block (from your examples I infer that your token consists of at least two blocks). Then, a better choice would be the CBC- or GCM-mode, see e.g. https://crypto.stackexchange.com/questions/20941/why-shouldnt-i-use-ecb-encryption and https://security.stackexchange.com/questions/6500/aes-ecb-mode-for-single-block-random-data-encryption. But since the Java encrypt-method seems to be your reference there is probably no way to change it.



          EDIT:



          The Java cipher-class determines automatically with the keysize if AES-128, AES-192 or AES-256 must be used. Therefore, you also have to know the size of the key in the context of the Java code. If the keysize is 16 byte then the choice of AES-128-ECB is correct, otherwise you have to adjust your PHP code accordingly (e.g. AES-192-ECB or AES-256-ECB for a 24 byte or a 32 byte keysize, respectively).






          share|improve this answer

























          • Yes! AES-128-ECB! Thank you!! You just saved my life. I tried every method list in php.net/manual/en/function.openssl-get-cipher-methods.php. But did not notice there are more methods and did not call openssl_get_cipher_methods by my self. What big mistake. Thank you, again.

            – crazyjin
            Nov 18 '18 at 9:39















          2














          Under the assumption that the Java side uses the SunJCE-Provider the default mode is the ECB-mode and the default padding is the PKCS5Padding i.e. Cipher.getInstance("AES") is identical to Cipher.getInstance("AES/ECB/PKCS5Padding") see e.g. https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#ciphertrans.



          The ECB-mode doesn't use an IV. Thus, you have to replace in your PHP generate_token-method



          $iv = self::hex_to_str("00000000000000000000000000000000");
          $token = openssl_encrypt($token_text, "AES-128-CBC", $key, 0, $iv);


          with



          $token = openssl_encrypt($token_text, "AES-128-ECB", $key, 0);


          Example:



          encrypt("This is the key!".getBytes(), "This is a plain text that needs to be encrypted...");


          provides



          fLSh/HoQkrsIVBtZJVnuIRqcz4ztUBDkDG9Pi3xe49Q9hh9zDzWZDRHEO70ixfLf2WbWYSeDOQ/ONFTWHW9i0Q==


          which is identical to the result of the PHP code (for the same key and plain text).



          Generally, the ECB-mode is not secure if you have more than one block (from your examples I infer that your token consists of at least two blocks). Then, a better choice would be the CBC- or GCM-mode, see e.g. https://crypto.stackexchange.com/questions/20941/why-shouldnt-i-use-ecb-encryption and https://security.stackexchange.com/questions/6500/aes-ecb-mode-for-single-block-random-data-encryption. But since the Java encrypt-method seems to be your reference there is probably no way to change it.



          EDIT:



          The Java cipher-class determines automatically with the keysize if AES-128, AES-192 or AES-256 must be used. Therefore, you also have to know the size of the key in the context of the Java code. If the keysize is 16 byte then the choice of AES-128-ECB is correct, otherwise you have to adjust your PHP code accordingly (e.g. AES-192-ECB or AES-256-ECB for a 24 byte or a 32 byte keysize, respectively).






          share|improve this answer

























          • Yes! AES-128-ECB! Thank you!! You just saved my life. I tried every method list in php.net/manual/en/function.openssl-get-cipher-methods.php. But did not notice there are more methods and did not call openssl_get_cipher_methods by my self. What big mistake. Thank you, again.

            – crazyjin
            Nov 18 '18 at 9:39













          2












          2








          2







          Under the assumption that the Java side uses the SunJCE-Provider the default mode is the ECB-mode and the default padding is the PKCS5Padding i.e. Cipher.getInstance("AES") is identical to Cipher.getInstance("AES/ECB/PKCS5Padding") see e.g. https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#ciphertrans.



          The ECB-mode doesn't use an IV. Thus, you have to replace in your PHP generate_token-method



          $iv = self::hex_to_str("00000000000000000000000000000000");
          $token = openssl_encrypt($token_text, "AES-128-CBC", $key, 0, $iv);


          with



          $token = openssl_encrypt($token_text, "AES-128-ECB", $key, 0);


          Example:



          encrypt("This is the key!".getBytes(), "This is a plain text that needs to be encrypted...");


          provides



          fLSh/HoQkrsIVBtZJVnuIRqcz4ztUBDkDG9Pi3xe49Q9hh9zDzWZDRHEO70ixfLf2WbWYSeDOQ/ONFTWHW9i0Q==


          which is identical to the result of the PHP code (for the same key and plain text).



          Generally, the ECB-mode is not secure if you have more than one block (from your examples I infer that your token consists of at least two blocks). Then, a better choice would be the CBC- or GCM-mode, see e.g. https://crypto.stackexchange.com/questions/20941/why-shouldnt-i-use-ecb-encryption and https://security.stackexchange.com/questions/6500/aes-ecb-mode-for-single-block-random-data-encryption. But since the Java encrypt-method seems to be your reference there is probably no way to change it.



          EDIT:



          The Java cipher-class determines automatically with the keysize if AES-128, AES-192 or AES-256 must be used. Therefore, you also have to know the size of the key in the context of the Java code. If the keysize is 16 byte then the choice of AES-128-ECB is correct, otherwise you have to adjust your PHP code accordingly (e.g. AES-192-ECB or AES-256-ECB for a 24 byte or a 32 byte keysize, respectively).






          share|improve this answer















          Under the assumption that the Java side uses the SunJCE-Provider the default mode is the ECB-mode and the default padding is the PKCS5Padding i.e. Cipher.getInstance("AES") is identical to Cipher.getInstance("AES/ECB/PKCS5Padding") see e.g. https://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#ciphertrans.



          The ECB-mode doesn't use an IV. Thus, you have to replace in your PHP generate_token-method



          $iv = self::hex_to_str("00000000000000000000000000000000");
          $token = openssl_encrypt($token_text, "AES-128-CBC", $key, 0, $iv);


          with



          $token = openssl_encrypt($token_text, "AES-128-ECB", $key, 0);


          Example:



          encrypt("This is the key!".getBytes(), "This is a plain text that needs to be encrypted...");


          provides



          fLSh/HoQkrsIVBtZJVnuIRqcz4ztUBDkDG9Pi3xe49Q9hh9zDzWZDRHEO70ixfLf2WbWYSeDOQ/ONFTWHW9i0Q==


          which is identical to the result of the PHP code (for the same key and plain text).



          Generally, the ECB-mode is not secure if you have more than one block (from your examples I infer that your token consists of at least two blocks). Then, a better choice would be the CBC- or GCM-mode, see e.g. https://crypto.stackexchange.com/questions/20941/why-shouldnt-i-use-ecb-encryption and https://security.stackexchange.com/questions/6500/aes-ecb-mode-for-single-block-random-data-encryption. But since the Java encrypt-method seems to be your reference there is probably no way to change it.



          EDIT:



          The Java cipher-class determines automatically with the keysize if AES-128, AES-192 or AES-256 must be used. Therefore, you also have to know the size of the key in the context of the Java code. If the keysize is 16 byte then the choice of AES-128-ECB is correct, otherwise you have to adjust your PHP code accordingly (e.g. AES-192-ECB or AES-256-ECB for a 24 byte or a 32 byte keysize, respectively).







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 17 '18 at 8:33

























          answered Nov 16 '18 at 21:53









          TopacoTopaco

          1,577139




          1,577139












          • Yes! AES-128-ECB! Thank you!! You just saved my life. I tried every method list in php.net/manual/en/function.openssl-get-cipher-methods.php. But did not notice there are more methods and did not call openssl_get_cipher_methods by my self. What big mistake. Thank you, again.

            – crazyjin
            Nov 18 '18 at 9:39

















          • Yes! AES-128-ECB! Thank you!! You just saved my life. I tried every method list in php.net/manual/en/function.openssl-get-cipher-methods.php. But did not notice there are more methods and did not call openssl_get_cipher_methods by my self. What big mistake. Thank you, again.

            – crazyjin
            Nov 18 '18 at 9:39
















          Yes! AES-128-ECB! Thank you!! You just saved my life. I tried every method list in php.net/manual/en/function.openssl-get-cipher-methods.php. But did not notice there are more methods and did not call openssl_get_cipher_methods by my self. What big mistake. Thank you, again.

          – crazyjin
          Nov 18 '18 at 9:39





          Yes! AES-128-ECB! Thank you!! You just saved my life. I tried every method list in php.net/manual/en/function.openssl-get-cipher-methods.php. But did not notice there are more methods and did not call openssl_get_cipher_methods by my self. What big mistake. Thank you, again.

          – crazyjin
          Nov 18 '18 at 9:39



















          draft saved

          draft discarded
















































          Thanks for contributing an answer to Stack Overflow!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid


          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.

          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53339751%2fopenssl-encrypt-aes-encrypt-with-out-vector%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

          Top Tejano songwriter Luis Silva dead of heart attack at 64

          ReactJS Fetched API data displays live - need Data displayed static

          政党