title: When decrypting in RSA using Java BigIntegers, how do I preserve a zero byte at the beginning of the original data?
body: <p>I am implementing my own version of RSA, along with the padding scheme RSA-OAEP in Java. This is my code for the basic algorithm:</p>
  
  <pre><code>public byte[] encrypt(byte[] data, RSA_PublicKey publicKey) {
     BigInteger message = new BigInteger(data);
     BigInteger n = publicKey.getModulus(); //RSA Modulus
     BigInteger e = publicKey.getPublicExponent(); //RSA Public Exponent
     if (message.compareTo(n) &gt;= 0) {
         throw new InvalidDataException();
     }
     byte[] cipherText = message.modPow(e, n).toByteArray(); //Encryption
     return cipherText;
  }
  
  public byte[] decrypt(byte[] data, RSA_PrivateKey privateKey) {
     BigInteger cipherText = new BigInteger(data);
     BigInteger n = privateKey.getModulus(); //RSA Modulus
     BigInteger d = privateKey.getPrivateExponent(); //RSA Private Exponent
     if (cipherText.compareTo(n) &gt;= 0) {
         throw new InvalidDataException();
     }
     if (cipherText.compareTo(n.subtract(BigInteger.ONE)) == 1) {
         throw new InvalidDataException();
     }
     byte[] message = cipherText.modPow(d, n).toByteArray(); //Decryption
     return message;
  }
  </code></pre>
  
  <p>In RSA-OAEP, a series of operations are performed on the data and a random seed using a mask generation function before encryption. A zero byte is placed in front of the padded data. This is what it looks like in my code:</p>
  
  <pre><code>buffer = ByteBuffer.allocate(k);
  buffer.put((byte)0);
  buffer.put(maskedSeed);
  buffer.put(maskedDB);
  byte[] em = buffer.array();
  byte[] cipherText = encrypt(em, publicKey);
  return cipherText
  </code></pre>
  
  <p>When I decrypt this ciphertext, sometimes the zero byte is still in the resulting byte array, and other times it is not. For example, this data (in hex) was the same before encryption and after decryption:</p>
  
  <p>00c127a743b56f53e46223eba367b63d3378648c1d5ce3e8eec1f714c099a15b674c528d5051c1c9a32dc39fb13ee745864c7f572fa950dc8336a54d89503754f6c18dd463ec1633e6e94638230d9b10cc6e2904f4c69247a8bac0c60885b37b8adefe3b682b3a6d39f445447fa2f173b408346d3d0db086e199ef9c1fd0d14f</p>
  
  <p>However, this data:</p>
  
  <p>001c924b794c178c9955d4f3211c67ecda59ffe8c4be55c101bcd5ff3ce0a746ca447b5fc8fd8725cbb083e4b9244cf49b6ca84465680c0c49bec2bab3dfab6371673f0d01605d641330592ffb8915229c2dc4ea1ffcdf8a9a0e461fdf224f5cf57f74affac9d35dd3ce61ff1dd068a8c9495290735415984ddb71515823f746</p>
  
  <p>was decrypted as this:</p>
  
  <p>1c924b794c178c9955d4f3211c67ecda59ffe8c4be55c101bcd5ff3ce0a746ca447b5fc8fd8725cbb083e4b9244cf49b6ca84465680c0c49bec2bab3dfab6371673f0d01605d641330592ffb8915229c2dc4ea1ffcdf8a9a0e461fdf224f5cf57f74affac9d35dd3ce61ff1dd068a8c9495290735415984ddb71515823f746</p>
  
  <p>According to the RSA standard, the decrypted padded data is supposed to be checked for this zero byte to ensure it is properly padded, and to return an error message if it is not. I believe this has something to do with the fact that BigIntegers are signed. Is there some workaround for this issue?</p>