title: Android: Encrypt String, send via HTTPS and Decrypt String problem
body: <p>I have to Encrypt a String to send via HTTPS to a server. Then, on server side, I have to Decrypt the string and used it.</p>
  
  <p>I used this code in both sides:</p>
  
  <pre><code>public class SimpleCrypto {
  
  public static String encrypt(String seed, String cleartext) throws Exception {
  
      byte[] rawKey = getRawKey(seed.getBytes());
  
      byte[] result = encrypt(rawKey, cleartext.getBytes());
  
      return toHex(result);
  }
  
  public static String decrypt(String seed, String encrypted) throws Exception {
  
      byte[] rawKey = getRawKey(seed.getBytes());
  
      byte[] enc = toByte(encrypted);
  
      byte[] result = decrypt(rawKey, enc);
  
      return new String(result);
  }
  
  private static byte[] getRawKey(byte[] seed) throws Exception {
  
      KeyGenerator kgen = KeyGenerator.getInstance("AES");
  
      SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
  
      sr.setSeed(seed);
  
      kgen.init(128, sr); // 192 and 256 bits may not be available
  
      SecretKey skey = kgen.generateKey();
  
      byte[] raw = skey.getEncoded();
  
      return raw;
  }
  
  
  private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
  
      SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
  
      Cipher cipher = Cipher.getInstance("AES");
  
      cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
  
      byte[] encrypted = cipher.doFinal(clear);
  
      return encrypted;
  }
  
  private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
  
      SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
  
      Cipher cipher = Cipher.getInstance("AES");
  
      cipher.init(Cipher.DECRYPT_MODE, skeySpec);
  
      byte[] decrypted = cipher.doFinal(encrypted);
  
      return decrypted;
  }
  
  public static String toHex(String txt) {
  
      return toHex(txt.getBytes());
  }
  public static String fromHex(String hex) {
  
      return new String(toByte(hex));
  }
  
  public static byte[] toByte(String hexString) {
  
      int len = hexString.length()/2;
  
      byte[] result = new byte[len];
  
      for (int i = 0; i &lt; len; i++)
          result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
  
      return result;
  }
  
  public static String toHex(byte[] buf) {
  
      if (buf == null)
          return "";
  
      StringBuffer result = new StringBuffer(2*buf.length);
  
      for (int i = 0; i &lt; buf.length; i++) {
              appendHex(result, buf[i]);
      }
  
      return result.toString();
  }
  
  private final static String HEX = "0123456789ABCDEF";
  
  private static void appendHex(StringBuffer sb, byte b) {
  
      sb.append(HEX.charAt((b&gt;&gt;4)&amp;0x0f)).append(HEX.charAt(b&amp;0x0f));
  }
  
  }
  </code></pre>
  
  <p>On android, using "123456789" as a seed the rawKey give me:</p>
  
  <p>[99, 51, -103, -58, 81, -52, 90, -103, -114, 70, -128, -25, -105, -124, -128, -67]</p>
  
  <p>But on Server side, using the same seed, give me:</p>
  
  <p>[-52, 103, 4, 60, 123, -49, -11, -18, -91, 86, 107, -39, -79, -13, -57, 79]</p>
  
  <p>I can't understand why. Is diferent the javax.crypto.KeyGenerator on Android?, I'm making something bad?</p>
  
  <p>Please, I need some help.</p>
  
  <p>Thank you very much</p>
  
  <p>Sorry for my poor english</p>
  
  <p>-----------------------------UPDATE--------------------------------------------------------</p>
  
  <p>This is my new code:</p>
  
  <pre><code>public class DesEncrypter {
  
      public static final int SALT_LENGTH = 20;
      public static final int PBE_ITERATION_COUNT = 1024;
  
      private static final String RANDOM_ALGORITHM = "SHA1PRNG";
      private static final String PBE_ALGORITHM = "PBEWithSHA256And256BitAES-CBC-BC";
      private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
  
  
      public byte[] encrypt(String password, String cleartext) {
  
          byte[] encryptedText = null;
  
          try {
              byte[] salt = "dfghjklpoiuytgftgyhj".getBytes();
  
              PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), salt, PBE_ITERATION_COUNT, 256);
  
              SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHSHAAND256BITAES-CBC-BC");
  
              SecretKey tmp = factory.generateSecret(pbeKeySpec);
  
              SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
  
              byte[] key = secret.getEncoded();
  
              Cipher encryptionCipher = Cipher.getInstance(CIPHER_ALGORITHM);   
  
              byte[] iv = generateIv();
  
              IvParameterSpec ivspec = new IvParameterSpec(iv);
  
              encryptionCipher.init(Cipher.ENCRYPT_MODE, secret, ivspec);
  
              encryptedText = encryptionCipher.doFinal(cleartext.getBytes());
  
          } catch (Exception e) {
              e.printStackTrace();
          }
  
          return encryptedText;
      }
  
      public String decrypt(String password, byte[] encryptedText) {
  
          String cleartext = "";
  
          try {
              byte[] salt = "dfghjklpoiuytgftgyhj".getBytes();
  
              PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), salt, PBE_ITERATION_COUNT, 256);
  
              SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHSHAAND256BITAES-CBC-BC");
  
              SecretKey tmp = factory.generateSecret(pbeKeySpec);
  
              SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
  
              byte[] key = secret.getEncoded();
  
              Cipher decryptionCipher = Cipher.getInstance(CIPHER_ALGORITHM);
  
              byte[] iv = generateIv();
  
              IvParameterSpec ivspec = new IvParameterSpec(iv);
  
              decryptionCipher.init(Cipher.DECRYPT_MODE, secret, ivspec);
  
              byte[] decryptedText = decryptionCipher.doFinal(encryptedText);
  
              cleartext =  new String(decryptedText); 
  
          } catch (Exception e) {
              e.printStackTrace();
          }
  
          return cleartext;
      }   
  
      private byte[] generateIv() throws NoSuchAlgorithmException {
  
          SecureRandom random = SecureRandom.getInstance(RANDOM_ALGORITHM);
  
          byte[] iv = new byte[16];
  
          random.nextBytes(iv);
  
          return iv;
      }
  
  }
  </code></pre>
  
  <p>----------------------------FINALL CODE WORKING ON ANDROID!--------------------------------</p>
  
  <pre><code>import javax.crypto.Cipher;
  import javax.crypto.SecretKey;
  import javax.crypto.SecretKeyFactory;
  import javax.crypto.spec.IvParameterSpec;
  import javax.crypto.spec.PBEKeySpec;
  import javax.crypto.spec.SecretKeySpec;
  
  public class DesEncrypter {
  
      public static final int SALT_LENGTH = 20;
      public static final int PBE_ITERATION_COUNT = 200; //1024;
  
      private static final String PBE_ALGORITHM = "PBEWithSHA256And256BitAES-CBC-BC";
  
      //algoritmo / modo / relleno 
      private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
  
      byte[] iv = "1234567890asdfgh".getBytes();
  
      byte[] salt = "dfghjklpoiuytgftgyhj".getBytes();
  
      public byte[] encrypt(String password, String cleartext) {
  
          byte[] encryptedText = null;
  
          try {
  
  
              PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), salt, PBE_ITERATION_COUNT, 256);
  
              //Factoria para crear la SecretKey, debemos indicar el Algoritmo
              SecretKeyFactory factory = SecretKeyFactory.getInstance(PBE_ALGORITHM);
  
              SecretKey tmp = factory.generateSecret(pbeKeySpec);
  
              //Creamos una llave;
              SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
  
              //Obtenemos la llave, solo informativo
              byte[] key = secret.getEncoded();
  
              //La clase Cipher, se usa para cifrar mediante algoritmos de  clave simétrica
              Cipher encryptionCipher = Cipher.getInstance(CIPHER_ALGORITHM);   
  
              //byte[] iv = generateIv();
  
              IvParameterSpec ivspec = new IvParameterSpec(iv);
  
              //Accion, SecretKey, parameter specification for an initialization vector
              encryptionCipher.init(Cipher.ENCRYPT_MODE, secret, ivspec);
  
              //Realizamos el cifrado
              encryptedText = encryptionCipher.doFinal(cleartext.getBytes());
  
          } catch (Exception e) {
              e.printStackTrace();
          }
  
          return encryptedText;
      }
  
      public String decrypt(String password, byte[] encryptedText) {
  
          String cleartext = "";
  
          try {
  
              PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), salt, PBE_ITERATION_COUNT, 256);
  
              //Factoria para crear la SecretKey, debemos indicar el Algoritmo
              SecretKeyFactory factory = SecretKeyFactory.getInstance(PBE_ALGORITHM);
  
              SecretKey tmp = factory.generateSecret(pbeKeySpec);
  
              //Creamos una llave;
              SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
  
              //Obtenemos la llave, solo informativo
              byte[] key = secret.getEncoded();
  
              //La clase Cipher, se usa para cifrar mediante algoritmos de  clave simétrica
              Cipher decryptionCipher = Cipher.getInstance(CIPHER_ALGORITHM);
  
              //byte[] iv = generateIv();
  
              IvParameterSpec ivspec = new IvParameterSpec(iv);
  
              //Accion, SecretKey, parameter specification for an initialization vector
              decryptionCipher.init(Cipher.DECRYPT_MODE, secret, ivspec);
  
              //Realizamos el descifrado
              byte[] decryptedText = decryptionCipher.doFinal(encryptedText);
  
              cleartext =  new String(decryptedText); 
  
          } catch (Exception e) {
              e.printStackTrace();
          }
  
          return cleartext;
      }      
  }
  </code></pre>