I'm getting the error "BadPaddingException : data must start with zero" even though the data does start with zero
<p>As a learning exercise, I'm building a chat server in Java, and a client in C#. I'm using RSA and AES to encrypt the messages before they're sent. The problem is that I'm having trouble encrypting and decrypting the AES key using RSA. </p>

<p>The server loads its private and public RSA keys from a file via serialization, or generates a new key pair if the file isn't found:</p>

<pre><code>public RSA(ChatServer chatServer) {
    this.server = chatServer;
    try {
        FileInputStream fileInputStream = new FileInputStream("rsa.key");
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
        keyPair = (KeyPair)objectInputStream.readObject();
        objectInputStream.close();
        chatServer.log("RSA key pair loaded.");
    } catch (FileNotFoundException e) {
        chatServer.logWarning("No RSA key found.");
        chatServer.log("Generating new RSA key pair (This may take a few moments)...");
        keyPair = this.generateKeyPair();
        try {
            this.saveKeys();
        } catch (IOException ioe) {
            this.server.logException(ioe);
        }
    } catch (Exception e) {
        this.server.logException(e);
    }
}

public KeyPair generateKeyPair() {
    KeyPairGenerator kpg;
    try {
        kpg = KeyPairGenerator.getInstance("RSA");

        kpg.initialize(3072);

        return kpg.generateKeyPair();
    } catch (Exception e) {
        this.server.logException(e);
        return null;
    }
}

public void saveKeys() throws IOException {
    ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream("rsa.key")));

    try {
        oout.writeObject(this.keyPair);
    } catch (Exception e) {
        this.server.logException(e);
    } finally {
        oout.close();
    }
}
</code></pre>

<p>When a client connects, the server converts its public key to the XML format used by .NET and sends it:</p>

<pre><code>public String getPublicKeyXML() {
    try {
        KeyFactory factory = KeyFactory.getInstance("RSA");
        RSAPublicKeySpec publicKey = factory.getKeySpec(this.keyPair.getPublic(), RSAPublicKeySpec.class);

        byte[] modulus = publicKey.getModulus().toByteArray();
        byte[] exponent = publicKey.getPublicExponent().toByteArray();

        String modulusStr = Base64.encodeBytes(modulus);
        String exponentStr = Base64.encodeBytes(exponent);

        String format = 
            "&lt;RSAKeyValue&gt;" +
                "&lt;Modulus&gt;%s&lt;/Modulus&gt;" +
                "&lt;Exponent&gt;%s&lt;/Exponent&gt;" +
            "&lt;/RSAKeyValue&gt;";

        return String.format(format, modulusStr, exponentStr);
    } catch (Exception e) {
        this.server.logException(e);
        return null;
    }
}
</code></pre>

<p>The client receives the key fine and loads it without a fuss. The client then encrypts a randomly chosen AES key to send to the server (Note that this code is from the client and therefore in C# rather than Java):</p>

<pre><code>public static byte[] encrypt(string xmlKey, byte[] bytes)
{
    RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
    rsa.FromXmlString(xmlKey);
    System.Diagnostics.Debug.WriteLine(rsa.ToXmlString(false));
    byte[] cipherBytes = rsa.Encrypt(bytes, false);
    rsa.Clear();
    return cipherBytes;
}
</code></pre>

<p>The public key printed by this code is the same one that is sent by the server, and so far everything appears to be working perfectly. The problem occurs when the server tries to decrypt it:</p>

<pre><code>public byte[] decrypt(byte[] data) {
    try {
        PrivateKey privateKey = this.keyPair.getPrivate();
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        this.server.logDebug("Decrypting data: " + this.bytesToHex(data));
        byte[] cipherData = cipher.doFinal(data);
        return cipherData;
    } catch (Exception e) {
        this.server.logException(e);
        return new byte[0];
    }
}
</code></pre>

<p>Here's where things get strange. I'm getting a BadPaddingException telling me that the data has to start with 0; however, as a debugging measure I've had the server print out the data to be decrypted and the first byte is, in fact, 00! I'm at a loss as to what to do, and Google hasn't turned up anyone else having this issue. Does anyone know what might be the problem here?</p>
