RSA (JCE) anders als RSA in C ?

oneneno

Mitglied
Hallo,

Ich habe folgende Code in C:

Code:
static unsigned char modulus[] = {
   0x00,0xcd,0x40,0x06,0x94,0xef,0xd2,0xd3,0xc0,0x65,0xca,0xfa,0x15,0x66,0x63,
   0x50,0x1f,0x8e,0x44,0xbe,0x6b,0x79,0x9a,0x21,0x42,0x86,0xf9,0x89,0x90,0xdd,
   0x95,0x9f,0xe3 };

static unsigned char publicExponent[] = { 0x01,0x00,0x01 };

void *
get_public_key (void)
{
	RSA *pub;

	if ((pub = RSA_new()) != NULL) {
#define		BN_INIT(name)	BN_bin2bn(name,sizeof(name),NULL)
		pub->n = BN_INIT(modulus);
		pub->e = BN_INIT(publicExponent);
		// RSA_print_fp (stdout, pub, 0);
		return ((void *) pub);
	}
	return (NULL);
}


int
encode (const char *cleartext, int length, char *buf, int bufsize)
{
	int size;
	unsigned char *decstr, *encstr;
	static RSA *pub = NULL;

	if ((pub == NULL) && ((pub = get_public_key()) == NULL)) {
		return (-ENOMEM);
	}

	size = RSA_size (pub);
	if (length > size) {
		return (-ENOSPC);
	}
	encstr = alloca (size+4);
	decstr = alloca (size+4);

	memset (decstr, 0, size);
	memcpy (decstr, cleartext, length);
	// decstr[length] = '\0';
	
	size = RSA_public_encrypt (size, decstr, encstr, pub, RSA_NO_PADDING);

	if ((size > 0) && (bufsize > ((4*size)/3) + 4)) {
		size = base64_encode (encstr, size, buf);
	} else {
		return ((size > 0)? -ENOSPC: -EINVAL);
	}

	return (size);
}

in Java convertiert:

Code:
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
		 
		String text ="1234";

        		
        // openssl rsa -pubin -in pubkey.pem -modulus -noout
		BigInteger modulus = new BigInteger("CD400694EFD2D3C065CAFA156663501F8E44BE6B799A214286F98990DD959FE3", 16);
		
		//openssl rsa -pubin -in pubkey.pem -text -noout
		BigInteger pubExp = new BigInteger("010001", 16);

		KeyFactory keyFactory = keyFactory = KeyFactory.getInstance("RSA","BC");

		RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(modulus, pubExp);
		
		RSAPublicKey key =  key = (RSAPublicKey) keyFactory.generatePublic(pubKeySpec);


		Cipher cipher = Cipher.getInstance("RSA/None/NoPadding", "BC");

		cipher.init(Cipher.ENCRYPT_MODE, key);
		byte[] cipherData = cipher.doFinal(text.getBytes());
            
        Base64 base64 = new Base64();
        System.out.println(base64.encodeToString(cipherData));


Leider das Ergebnis in Java ist nicht gleich wie in C code.

decstr in C code ist nur 4 byte lang

cipherData in java code aber 32 bytes lang ?!

Was habe ich denn falsch gemacht ? Gruss
 

oneneno

Mitglied
sorry, ich meine decstr ist natürlic h32 bytes lang und das ergebiss auch:
Nur ich bekomme in C code:

decstr = 31:32:33:34 als Eingabe

enstr =
9F:D4:C1:D3:86:37:09:AE:BA:41:7A:5E:A5:B5:26:6E:0A:70:E6:C5:A8:02:FD:58:B3:AC:59:A7:B4:FC:1A:0B

als Ergebnis.

Java code liefert aber
cipherData = B4CEED6011DD07831E6F1A45E2894D994039C96E8FDD4ED47044FE26912A6C4C
 
I

irgendjemand2

Gast
das problem könnte an unterschiedliche charsets liegen ... das halt String.getBytes() etwas anderes liefert als der code in C ...
vielleicht solltest du erstmal den input vergleichen


btw : entweder Base64 oder toHexString ... beides in ein ander macht keinen sinn und erhöt nur den overhead

base64 : 33%
hex : 50%
beides zusammen : um die 80% ...
 

oneneno

Mitglied
Ich habe vergessen zu erwähnen:

System.out.println( "text.getBytes=" + byteArrayToHexString(text.getBytes("UTF-8")));
oder
System.out.println( "text.getBytes=" + byteArrayToHexString(text.getBytes()));

liefert gleiche input: 31323334


Ich habe den Verdacht dass

Cipher.getInstance("RSA/None/NoPadding", "BC") nicht das gleiche Alg. wie openssl Funktion: RSA_public_encrypt

liefert
 
I

irgendjemand2

Gast
ich würde jetzt mal raten : versuche mal sowohl in deinem C-code als auch in java nur "RSA" zu verwenden ... in java geht das auf jeden fall ... und ich denek da BC die libs kompatibel geschrieben hat sollte das auch in C möglich sein ...

ist jetzt aber wie gesagt nur geraten ...

das es kompatibel ist kann man irgendwo auf der BC seite lesen ... vllt gibt es da auch ein beispiel zu ...

-----

wobei : ich sehe gerade das BC nur Java und C# libs anbietet ... und da du was von C und OpenSSL faselst kann es durch aus sein das diese inkompatibel zu ein ander sind ...
hier solltest du mal den normalen Sun-provider ausprobieren ... der sollte soweit zum OpenSSL kompatibel sein ... versprechen kann ich dir nichts ...

-----

tja ... wollte grad mal dein beispiel testen ... allerdings mit dem Sun provider ... der mir erstmal freundlicherweise sagte : RSA keys must be at least 512 bits long ...
und ich denke genau DAS wird das problem sein ... das alles den dienst verweigert weil der key einfach zu kurz ist ...

btw : könntest du mir mal verraten was "Base64" ist ? ... ich hab zwar die bc-lib geladen .. aber da meinte javac das es angeblich keine methode mit der signatur
[c]org.bouncycastle.util.encoders.Base64.encodeToString(byte[])[/c] gäbe ...

wäre also mal sinnvoll den kompletten source zu posten
 

oneneno

Mitglied
Ich benutze
org.apache.commons.codec.binary.Base64;

Am Anfang habe ich auch Sun-Provider benutzt, key musste aber 512 byte lang sein, da ich unser C project nicht ändern möchte habe ich BC genommen.
Ok, ich teste nochmals mit Sun -Provider.
Gruss
 
I

irgendjemand2

Gast
gut ... dann hättest du das vielleicht dazu schreiben sollen ... dann hätte man mal versuchen können deinen code in einen lauffähigen kontext zu setzen ...

da du allerdings nur das stück da und keinen lauffähigen code gepostet hast *bzw auch keine weiteren infos* und ich mir die mühe gemacht habe eine klasse mit diesem namen in der BC lib zu finden ... war das natürlich die falsche ...

btw : persönlich bin ich von Apache Commons sowieso nicht so der freund ...

ist ja auch egal ...

wo bitte ist es das problem den key auf 512 BIT (nicht BYTE ... das wäre zu viel) anzuheben ?
lass dir doch einfach einen entsprechender länge generieren *z.b. vom Sun-Provider in java und diesen dann mit getPublicExponent() , getPrivateExponent() und getModulus() ausgeben lassen ... *am besten mit Integer.toHexString()* und diesen dann erstmal testweise durch OpenSSL laufen lassen .. und wenn das sauber durchläuft kannst du diesen auch bestimmt in dein C projekt einbauen ...


wie gesagt : BC ist Java / C# ... es kann sein das es mit C / C++ und/oder OpenSSL inkompatibel ist ...

btw : frage : welche sprache und welche lib verwendest du genau ? dann könnte man dir bei google *falls du es nicht gefunden hast* mal was raussuchen ...
 

Ähnliche Java Themen

Neue Themen


Oben