# Problem mit RSA Verschlüsselung bei .net und Java



## Guest (19. Sep 2008)

Hallo,

ich versuche jetzt seit einigen Tagen RSA verschlüsselte Nachrichten zwischen .net und Java auszutauschen, aber irgendwie komme ich da auf keinen grünen Zweig. 

Ich habe dafür zu Testzwecken mit .Net ein Schlüsselpaar erzeugt und habe dieses jeweils in meinem Testprogrammen fest eingebunden. Ich kann auf beiden Seiten wunderbar mit diesen Schlüsselpaaren arbeiten, jedoch kann ich keine mit Java verschlüsselte Nachrichten mit .Net entschlüsseln und umgedreht. Ich bekomme jeweils eine Exception, was mich vermuten läßt das irgendwas mit dem Padding nicht richtig ist. Nach längerem Google habe ich viele Beträge mit ähnlichen Probleme gefunden, jedoch keine funktionierende Lösung.

Ich verwende Java 1.5_02.

Javaprogramm:

```
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import sun.misc.BASE64Decoder;


public class JavaDotNetRSA {
	/**
	 * Privater Schlüssel mit .Net erzeugt
	 */
	private static String privKey = "<RSAKeyValue><Modulus>waxamzN8z+quhFK1N9vT" +
			"k2F695NufKygh2cIMZO0zuKDQ+Yl4AnLTAgPbzZtEd54WutG9eeujksj5YVDwUpf6s" +
			"1iTBrYXqFEpz1t6OBjVr8x0qK0qihupAxFJ1RDsCpkAiMrco/41UYBCz//Bcq+2Uq" +
			"0XI2qFK/4C0Eaw+X+4D8=</Modulus><Exponent>AQAB</Exponent>

7JR2s4" +
			"9Vgevwj/ziWlQNq2rGl1yFmQyRPje8f6saHtaZh+y1G0TOrQAJhUETNOFfWqJJLTI" +
			"VP3iPuhBC2sBpRw==</P><Q>0ZI9tUlgiNTNhfI6TPsoO4yFyi6/vvct0xmLLKEJt" +
			"bMg1NgMANRTziFwE4zoPrN2h34GbzOGnDjrffbRwhXNSQ==</Q><DP>TczE/Ge2hv" +
			"NAORnAllPt6uFCTaRvitVHLl7F7nYmMN4Bv2FobX9DOEE64Ed2OX2kDfowdlxyAF1" +
			"1ZorScX21IQ==</DP><DQ>YeFMouwngyDo8MOGiUfQradfIWQeOEHYDD1k7C42i7+" +
			"i+OYDDSweDCs/3lG0cvx8wqGQvcUx/Kr1CfsKUvy9yQ==</DQ><InverseQ>sdS+k" +
			"PDdLKa9oXnxdhmSQ7IrKsIKjR2GcH+QUFw4SEALMdPOfXJGP3TGDYVZKkjxHTjHWb" +
			"IRCGAaBQSVq9SJdw==</InverseQ><D>HlyIr7/4lxexWCknI6SgnIAxqNJCBeWCH" +
			"Pf3/t2rAKvd7C0OTvr6FedFlCeyHZUExSwRKceyQ7hf3kFwB8NDGeQ7cWKEM8e00j" +
			"5Q0G86SpPbSOS6OoW53D/DL5LDagqjd5EQ1EzYCs1nEwxk0bwsZ/BjFUxVcaPFlBr" +
			"4LQiJCWE=</D></RSAKeyValue>";

	/**
	 * Öffentlicher Schlüssel mit .Net erzeugt
	 */
	private static String pubKey ="<RSAKeyValue><Modulus>waxamzN8z+quhFK1N9vTk" +
			"2F695NufKygh2cIMZO0zuKDQ+Yl4AnLTAgPbzZtEd54WutG9eeujksj5YVDwUpf6s" +
			"1iTBrYXqFEpz1t6OBjVr8x0qK0qihupAxFJ1RDsCpkAiMrco/41UYBCz//Bcq+2Uq" +
			"0XI2qFK/4C0Eaw+X+4D8=</Modulus><Exponent>AQAB</Exponent></RSAKeyV" +
			"alue>";
	
	/**
	 * Beispieltext zum Ver- unt Entschlüsseln
	 */
	private static String text = "Kurzer Beispieltext2";
	
	/**
	 * Beispieltext mit dem privaten Schlüssel in .Net verschlüsselt.
	 */
	public static byte[] netEncrypted = new byte[]{(byte) 0x19 ,(byte) 0xE9 ,
		(byte) 0x0D ,(byte) 0x07 ,(byte) 0x24 ,(byte) 0x20 ,(byte) 0xB3 ,(byte) 0xDD 
		,(byte) 0xB0 ,(byte) 0x95 ,(byte) 0xC7 ,(byte) 0xD2 ,(byte) 0x01 ,
		(byte) 0x7B ,(byte) 0x2F ,(byte) 0x2B ,(byte) 0xCB ,(byte) 0xD5 ,(byte) 0x20 
		,(byte) 0x77 ,(byte) 0x44 ,(byte) 0x2B ,(byte) 0xA0 ,(byte) 0x66 ,
		(byte) 0x86 ,(byte) 0xC5 ,(byte) 0x7E ,(byte) 0x8B ,(byte) 0xE7 ,(byte) 0x97 
		,(byte) 0xB2 ,(byte) 0x80 ,(byte) 0xE7 ,(byte) 0x6C ,(byte) 0x61 ,
		(byte) 0xE9 ,(byte) 0x15 ,(byte) 0xB7 ,(byte) 0x97 ,(byte) 0x76 ,(byte) 0xDD 
		,(byte) 0xB9 ,(byte) 0x0F ,(byte) 0x8D ,(byte) 0x4F ,(byte) 0x56 ,
		(byte) 0x98 ,(byte) 0xF1 ,(byte) 0x89 ,(byte) 0x41 ,(byte) 0x3B ,(byte) 0x9F 
		,(byte) 0xD5 ,(byte) 0x18 ,(byte) 0xAB ,(byte) 0xC8 ,(byte) 0xFF ,
		(byte) 0xE2 ,(byte) 0x79 ,(byte) 0xE4 ,(byte) 0x6C ,(byte) 0x53 ,(byte) 0xAC 
		,(byte) 0x79 ,(byte) 0x05 ,(byte) 0xA4 ,(byte) 0x24 ,(byte) 0x90 ,
		(byte) 0x0B ,(byte) 0x40 ,(byte) 0xD4 ,(byte) 0xC8 ,(byte) 0x98 ,(byte) 0xF3 
		,(byte) 0x43 ,(byte) 0x39 ,(byte) 0x92 ,(byte) 0x32 ,(byte) 0xBA ,
		(byte) 0xFD ,(byte) 0x25 ,(byte) 0x58 ,(byte) 0xFB ,(byte) 0x42 ,(byte) 0x3A 
		,(byte) 0xF3 ,(byte) 0x98 ,(byte) 0x08 ,(byte) 0xB3 ,(byte) 0x2B ,
		(byte) 0x46 ,(byte) 0x69 ,(byte) 0xAE ,(byte) 0xE6 ,(byte) 0x54 ,(byte) 0xE0 
		,(byte) 0x8A ,(byte) 0x56 ,(byte) 0x58 ,(byte) 0x9C ,(byte) 0x1F ,
		(byte) 0x59 ,(byte) 0xC2 ,(byte) 0x24 ,(byte) 0x21 ,(byte) 0x67 ,(byte) 0x7D 
		,(byte) 0x39 ,(byte) 0xCC ,(byte) 0x6C ,(byte) 0x91 ,(byte) 0x90 ,
		(byte) 0x1F ,(byte) 0xE6 ,(byte) 0xD8 ,(byte) 0xE8 ,(byte) 0x82 ,(byte) 0x32 
		,(byte) 0x11 ,(byte) 0xD2 ,(byte) 0x03 ,(byte) 0x6F ,(byte) 0xCF ,
		(byte) 0x58 ,(byte) 0x93 ,(byte) 0x07 ,(byte) 0x04 ,(byte) 0x94 };

	public static void main(String[] args) throws NoSuchAlgorithmException, 
	InvalidKeySpecException, NoSuchPaddingException, IOException, 
	NoSuchProviderException, InvalidKeyException, IllegalBlockSizeException, 
	BadPaddingException {
		//Schlüssel erzeugen
		RSAPrivateKey priv = generatePrivateKey();
		RSAPublicKey pub = generatePublicKey();

		//Chiper erzeguen
		Cipher c = Cipher.getInstance("RSA/ECB/PKCS1Padding","SunJCE");//PKCS1Padding
		
		//Testweise etwas mit Ver- und Entschlüsseln
		c.init(Cipher.ENCRYPT_MODE, priv);
		byte[] encrypt = c.doFinal(text.getBytes("UTF-8"));
		
		c.init(Cipher.DECRYPT_MODE, pub);
		byte[] decrypt = c.doFinal(encrypt);
		
		//true wenn entschlüsselter Text gleich dem unverschlüsseltem Text
		System.out.println("Ver- Entschlüsseln ok? " + 
				new String(decrypt, "UTF-8").equals(text));
		
		//Entschlüsseln des in .Net verschlüsseltem Textes
		byte[] encInDotNet = netEncrypted;
		c.init(Cipher.DECRYPT_MODE, pub);
		decrypt = c.doFinal(b);
		
		System.out.println( "Entschüsseln aus .NET ok? " +
				new String(decrypt, "UTF-8").equals(text));
	}
	
	/**
	 * Ließt den Privaten Schlüssel.
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws InvalidKeySpecException
	 * @throws NoSuchPaddingException
	 * @throws IOException
	 */
	private static RSAPrivateKey generatePrivateKey() throws NoSuchAlgorithmException, 
InvalidKeySpecException, NoSuchPaddingException, IOException{
		String mod = privKey.substring(privKey.indexOf("<Modulus>")
				+ "<Modulus>".length(), privKey.indexOf("</Modulus>"));
		String d = privKey.substring(privKey.indexOf("<D>") + "<D>".length(),
				privKey.indexOf("</D>"));
		
		byte[] byteModeP = new BASE64Decoder().decodeBuffer(mod);
		byte[] byteExpP = new BASE64Decoder().decodeBuffer(d);

		BigInteger modulus = new BigInteger(1, byteModeP);
		BigInteger exponent = new BigInteger(1, byteExpP);

		RSAPrivateKeySpec rsaPrivate = new RSAPrivateKeySpec(modulus, exponent);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		return (RSAPrivateKey) keyFactory.generatePrivate(rsaPrivate);
	}
	
	/**
	 * Ließt den öffentlichen Schlüssel
	 * @return
	 * @throws NoSuchAlgorithmException
	 * @throws InvalidKeySpecException
	 * @throws NoSuchPaddingException
	 * @throws IOException
	 */
	private static RSAPublicKey generatePublicKey() throws NoSuchAlgorithmException, 
InvalidKeySpecException, NoSuchPaddingException, IOException{
		String mod = pubKey.substring(pubKey.indexOf("<Modulus>")
				+ "<Modulus>".length(), pubKey.indexOf("</Modulus>"));
		String exp = pubKey.substring(pubKey.indexOf("<Exponent>")
				+ "<Exponent>".length(), pubKey.indexOf("</Exponent>"));
		
		byte[] byteModeP = new BASE64Decoder().decodeBuffer(mod);
		byte[] byteExpP = new BASE64Decoder().decodeBuffer(exp);

		BigInteger modulus = new BigInteger(1, byteModeP);
		BigInteger exponent = new BigInteger(1, byteExpP);

		RSAPublicKeySpec rsaPrivate = new RSAPublicKeySpec(modulus, exponent);
		KeyFactory keyFactory = KeyFactory.getInstance("RSA");
		return (RSAPublicKey) keyFactory.generatePublic(rsaPrivate);
	}
	
	/**
	 * Gibt ein Bytearray als Hexstring aus.
	 * @param data
	 * @return
	 */
	private static String simpleHexdump(byte[] data) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < data.length; i++) {

			// yea, Java has signed bytes in 2 complement :(
			int val = 0x000000FF & ((int) data[i]);
			String s = Integer.toHexString(val);
			
			if (s.length() < 2) {
				sb.append("0");
			}
			sb.append(s);

		}
		return sb.toString();
	}
}
```


.Net Programm:

```
using System;
using System.Collections.Generic;
using System.Text;
using System.Security.Cryptography;
namespace RSA
{
    class Program
    {

        static void Main(string[] args)
        {
        	CspParameters cspParams = new CspParameters();
  			cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
			
        	RSACryptoServiceProvider myrsa = new RSACryptoServiceProvider(cspParams);
        	
        	//Einlesen des Schlüssels
            myrsa.FromXmlString("<RSAKeyValue><Modulus>waxamzN8z+quhFK1N9vTk2F695NufKygh" +
        	                    "2cIMZO0zuKDQ+Yl4AnLTAgPbzZtEd54WutG9eeujksj5YVDwUpf6s1iTBr" +
        	                    "YXqFEpz1t6OBjVr8x0qK0qihupAxFJ1RDsCpkAiMrco/41UYBCz//Bcq+2" +
        	                    "Uq0XI2qFK/4C0Eaw+X+4D8=</Modulus><Exponent>AQAB</Exponent>

" +
        	                    "7JR2s49Vgevwj/ziWlQNq2rGl1yFmQyRPje8f6saHtaZh+y1G0TOrQAJhUE" +
        	                    "TNOFfWqJJLTIVP3iPuhBC2sBpRw==</P><Q>0ZI9tUlgiNTNhfI6TPsoO4y" +
        	                    "Fyi6/vvct0xmLLKEJtbMg1NgMANRTziFwE4zoPrN2h34GbzOGnDjrffbRwh" +
        	                    "XNSQ==</Q><DP>TczE/Ge2hvNAORnAllPt6uFCTaRvitVHLl7F7nYmMN4Bv2" +
        	                    "FobX9DOEE64Ed2OX2kDfowdlxyAF11ZorScX21IQ==</DP><DQ>YeFMouwngy" +
        	                    "Do8MOGiUfQradfIWQeOEHYDD1k7C42i7+i+OYDDSweDCs/3lG0cvx8wqGQvc" +
        	                    "Ux/Kr1CfsKUvy9yQ==</DQ><InverseQ>sdS+kPDdLKa9oXnxdhmSQ7IrKsI" +
        	                    "KjR2GcH+QUFw4SEALMdPOfXJGP3TGDYVZKkjxHTjHWbIRCGAaBQSVq9SJdw=" +
        	                    "=</InverseQ><D>HlyIr7/4lxexWCknI6SgnIAxqNJCBeWCHPf3/t2rAKvd7C" +
        	                    "0OTvr6FedFlCeyHZUExSwRKceyQ7hf3kFwB8NDGeQ7cWKEM8e00j5Q0G86SpP" +
        	                    "bSOS6OoW53D/DL5LDagqjd5EQ1EzYCs1nEwxk0bwsZ/BjFUxVcaPFlBr4LQiJ" +
        	                    "CWE=</D></RSAKeyValue>");
       
      		//Textencoding UTF8
            System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();

            //Beispieltext
            string data = "Kurzer Beispieltext";
            
            //Umwandeln in Byte
            Byte[] newdata = encoding.GetBytes(data);//convert to Bytes
             
            //Testweise verschlüsseln und entschlüsseln
            Byte[] encrypted = myrsa.Encrypt(newdata, false);
            Byte[] decrypted = myrsa.Decrypt(encrypted, false);
           
            Console.WriteLine("Entschlüsselt:  ");
            string dData = encoding.GetString(decrypted); 
            for (int i = 0; i < dData.Length; i++)
            {
                Console.Write("{0}", dData[i]);
          	}
            
            Console.WriteLine();
            Console.WriteLine();
            
			//Erneutes Entschlüsseln des in einem Vorherigen Lauf verschlüsseltem Textes
            Byte[] old  = new Byte[]{ 0x19 ,0xE9 ,0x0D ,0x07 ,0x24 ,0x20 ,0xB3 ,0xDD 
					,0xB0 ,0x95 ,0xC7 ,0xD2 ,0x01 ,0x7B ,0x2F ,0x2B ,0xCB ,0xD5 ,0x20 
					,0x77 ,0x44 ,0x2B ,0xA0 ,0x66 ,0x86 ,0xC5 ,0x7E ,0x8B ,0xE7 ,0x97 
					,0xB2 ,0x80 ,0xE7 ,0x6C ,0x61 ,0xE9 ,0x15 ,0xB7 ,0x97 ,0x76 ,0xDD 
					,0xB9 ,0x0F ,0x8D ,0x4F ,0x56 ,0x98 ,0xF1 ,0x89 ,0x41 ,0x3B ,0x9F 
					,0xD5 ,0x18 ,0xAB ,0xC8 ,0xFF ,0xE2 ,0x79 ,0xE4 ,0x6C ,0x53 ,0xAC 
					,0x79 ,0x05 ,0xA4 ,0x24 ,0x90 ,0x0B ,0x40 ,0xD4 ,0xC8 ,0x98 ,0xF3 
					,0x43 ,0x39 ,0x92 ,0x32 ,0xBA ,0xFD ,0x25 ,0x58 ,0xFB ,0x42 ,0x3A 
					,0xF3 ,0x98 ,0x08 ,0xB3 ,0x2B ,0x46 ,0x69 ,0xAE ,0xE6 ,0x54 ,0xE0 
					,0x8A ,0x56 ,0x58 ,0x9C ,0x1F ,0x59 ,0xC2 ,0x24 ,0x21 ,0x67 ,0x7D 
					,0x39 ,0xCC ,0x6C ,0x91 ,0x90 ,0x1F ,0xE6 ,0xD8 ,0xE8 ,0x82 ,0x32 
					,0x11 ,0xD2 ,0x03 ,0x6F ,0xCF ,0x58 ,0x93 ,0x07 ,0x04 ,0x94 };

     		decrypted = myrsa.Decrypt(old, false);
            Console.WriteLine("Alt Entschlüsselt:  ");
            dData = encoding.GetString(decrypted);  
            for (int i = 0; i < dData.Length; i++)
            {
                Console.Write("{0}", dData[i]);
            }
            
            Console.WriteLine();
            Console.WriteLine();
            
            //In Java verschlüsslt
            Byte[] java = new byte[]{0x92, 0x4d, 0xb5, 0x11, 0x2a, 0x9b, 0x24, 0xc7, 
            	0x7f, 0x5a, 0x5d, 0x63, 0x65, 0xac, 0xc0, 0x40, 0xce, 0xda, 0x3d, 0xfd, 
            	0x8c, 0x09, 0x18, 0x45, 0x6a, 0x02, 0x76, 0xfc, 0x37, 0x1a, 0x43, 0x11, 
            	0xbb, 0x27, 0x48, 0xb0, 0x20, 0x10, 0xd5, 0xcd, 0xf4, 0xf5, 0xec, 0x69, 
            	0x96, 0x36, 0x4b, 0x5a, 0x45, 0xa3, 0xfe, 0x9e, 0x63, 0x8f, 0xff, 0xe9, 
            	0x5c, 0x33, 0x2d, 0xc1, 0xbe, 0x7d, 0xc2, 0xa7, 0x80, 0xef, 0x78, 0xec, 
            	0x47, 0xc4, 0x18, 0x1a, 0xd9, 0x11, 0x3e, 0x7d, 0x56, 0x36, 0xe8, 0xca, 
            	0x2e, 0x2f, 0xd9, 0x17, 0x1d, 0x1c, 0xfe, 0x20, 0x21, 0x5f, 0xe1, 0xc3, 
            	0x0c, 0x91, 0x42, 0x8f, 0x27, 0x62, 0x6c, 0x5a, 0x2f, 0xf5, 0xd7, 0x2c, 
            	0x0d, 0x84, 0x1c, 0xaf, 0x03, 0x87, 0x70, 0x45, 0xf6, 0xbf, 0x2e, 0xac, 
            	0xdc, 0x80, 0x39, 0xcf, 0xb5, 0x8e, 0x0a, 0x8f, 0x19, 0xe2, 0xe6, 0xc0};

            decrypted = myrsa.Decrypt(java, false);
            Console.WriteLine("Java Entschlüsselt:  ");
            dData = encoding.GetString(decrypted);  
            for (int i = 0; i < dData.Length; i++)
            {
                Console.Write("{0}", dData[i]);
            }

			Console.Write("\nPress any key to continue . . . ");
			Console.ReadKey(true);
        }
    }
}
```


Für mögliche Lösung danke ich schonmal im vorraus.

Gruß Locu


----------



## Locutus2k (19. Sep 2008)

Hm jetzt habe ich doch glatt vergessen die Exeption zu Posten:

Exception in thread "main" javax.crypto.BadPaddingException: Data must start with zero
	at sun.security.rsa.RSAPadding.unpadV15(Unknown Source)
	at sun.security.rsa.RSAPadding.unpad(Unknown Source)
	at com.sun.crypto.provider.RSACipher.a(DashoA6275)
	at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA6275)
	at javax.crypto.Cipher.doFinal(DashoA12275)
	at JavaDotNetRSA.main(JavaDotNetRSA.java:109)


----------

