title: How can I encrypt/decrypt 12-digit decimal numbers to other ones, using a password and Java?
body: <p>I have already read <a href="https://stackoverflow.com/questions/321787/using-java-to-encrypt-integers">Using Java to encrypt integers</a> and <a href="http://www.exampledepot.com/egs/javax.crypto/PassKey.html" rel="nofollow noreferrer">Encrypting with DES Using a Pass Phrase</a>.</p>
  
  <p>All I need is a simple Encrypter which transforms a 12 digit number to a 12 digit number with the following constraints:</p>
  
  <ol>
  <li>The encryption must depend on a password (which will be constant throughout the life time of an application) and nothing else.</li>
  <li>The mapping must be 1-1 (No hashing and multiple inputs giving same output and vice versa).</li>
  <li>The mapping must not change between different VMs or when VM is started (like when you restart Java, the utility should give you same mappings which means that it must be purely dependent on the password that is supplied).</li>
  <li>Numbers starting with 0 is not a valid 12 digit number (also input numbers won't start with 0).</li>
  <li>The key/password should never be guessable. For example running the utility with multiple inputs and analysing the outputs should not allow one to guess the key/pwd/hash or whatever.</li>
  <li>All inputs will be exactly 12 digits and less than a 12 digit prime number (which means we could use modulo arithmetic). </li>
  </ol>
  
  <p>Having trawled through the literature I have this code with me </p>
  
  <pre><code>public void mytestSimple(long code, String password) throws Exception {
      SecretKey key = new SecretKeySpec(password.getBytes(), "DES");
      Cipher ecipher = Cipher.getInstance("DES");
      ecipher.init(Cipher.ENCRYPT_MODE, key);
      System.out.println(ecipher.getOutputSize(8));
  
      byte[] encrypted = ecipher.doFinal(numberToBytes(code));
      System.out.println(encrypted + "--" + encrypted.length);
  
      Cipher dcipher = Cipher.getInstance("DES");
      dcipher.init(Cipher.DECRYPT_MODE, key);
      byte[] decrypted = dcipher.doFinal(encrypted);
      System.out.println(bytesToNumber(decrypted) + "--" + decrypted.length);
  }
  
  public void testSimple() throws Exception {
      mytestSimple(981762654986L, "password");
  }
  </code></pre>
  
  <p>I am running into problems as to </p>
  
  <ol>
  <li>How to convert the 16 bytes into a 12 digit number.</li>
  <li>Maintain 1-1 mapping.</li>
  <li>Keep the encryption/decryption same across multiple VM invocations.</li>
  </ol>
  
  <p>**** Answer added by me below****</p>
  
  <p>I have added one answer which is a 40bit RSA pulled out of standard Java RSA keypair gen logic. I still have to work on the edge cases. I am going to accept the answer and upvote "Tadmas" who I think kinda lead me to the answer. Can someone tell me if my algorithm is going to be weak/attackable?</p>