Problem öffentlichen Schlüssel bei Cipher Decryption

  • Themenstarter Themenstarter CK
  • Beginndatum Beginndatum
Status
Nicht offen für weitere Antworten.

CK

Aktives Mitglied
Hallo Leute,
Mein Programm soll eine Signature verifizieren. Dazu übergebe ich eine Signature, Nachricht, den Modulus
und den Exponent. Dabei tritt das Problem auf das wenn ich mir Testweise ein Schlüsselpaar generieren lasse
und dann eine Signature erzeuge und die überprüfe funktioniert alles wunderbar. Aber wenn ich meinen PublicKey nehme und meine Signatur aus nen File dann bekomme ich verschiedene Exceptions (Näheres dazu im Code).

Hoffe ihr könnt mir helfen. Sitze jetzt mittlerweile eine Woche an diesen Problem.

Meine Vermutung wäre das ich meinen Schlüssel falsch verwende, aber da weis ich zur Zeit auch keine Lösung.

Die Main Klasse
Code:
import java.security.MessageDigest;
import java.security.PublicKey;
import javax.crypto.Cipher;
import org.bouncycastle.asn1.ASN1InputStream;
import org.bouncycastle.asn1.ASN1OctetString;
import org.bouncycastle.asn1.ASN1Sequence;


public class SigTest
{
    public static void main(String[] args)throws Exception
    {

        //Hier steht dann die Signatur aus dem file.
        byte sigBytes[] = Operations.stringToByteArray(args[0]); //args[0] ist 512 Byte groß
	                                                                            //Nach dem umwandeln 256 Byte
        Operations.printOutByteArray(sigBytes,"Signature");	//Ausgeben der Signatur
    							     
        //hier steht dann die Nachricht.
        byte[] message = Operations.stringToByteArray(args[1]); //args[1] ist 280 Byte      							         //Nach umwandeln 140 Byte
        Operations.printOutByteArray(message, "Message: "); //Ausgeben der Signatur
  
		// Cipher erstellen.        
        Cipher cipher = Cipher.getInstance("RSA/NONE/PKCS1PADDING", "BC");		        		         
        
        //erzeugen eines RSA Public Keys (übergebe ich Modulus und Exponent)
        PublicKey pubK = Operations.getPubKey(args[2],args[3]);	//args[2] ist 256 Byte und args[3] 6 Byte
        Operations.printOutByteArray(pubK.toString().getBytes(), "Static Key Bytes: ");
        Operations.printOutByteArray(pubK.getEncoded(),"Static Key Encoded: ");
              
        //Decrypt Mode
        cipher.init(Cipher.DECRYPT_MODE, pubK);
        cipher.update(sigBytes); //hier wirft er eine Exception (too much data for RSA block).
        /* wenn ich Schlüssel generieren lasse und damit eine Signatur erzeuge
         * und diese dann entschlüssele dann tritt hier kein Fehler auf.
         * Allerdings wenn ich meinen eigenen Public Key verwende, bekomme
         * ich die Exception (javax.crypto.BadPaddingException: unknown block type) 
         */
        byte[]  decSig = cipher.doFinal(); 
        Operations.printOutByteArray(decSig,"Decrypted Signature: ");
        
        // parse the signature
        ASN1InputStream	aIn = new ASN1InputStream(decSig);
        ASN1Sequence	seq = (ASN1Sequence)aIn.readObject();
    
        // grab a digest of the correct type
        MessageDigest	hash = MessageDigest.getInstance("SHA-1", "BC");
        hash.update(message);

        ASN1OctetString	sigHash = (ASN1OctetString)seq.getObjectAt(1);
        
        //Hier gebe ich mir beide Digest aus. Diese sollten übereinstimmen.
        Operations.printOutByteArray(hash.digest(),"Digest von der Message :");           
        Operations.printOutByteArray(sigHash.getOctets(),"Decrypted Digest aus der Signature :");
	}	
}

Die Operations Klasse
Code:
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PublicKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;


public abstract class Operations 
{
	/**
	 * Change a String to a byte array.
	 * @param text The Text which should change.
	 * @return the byte array.
	 */
	public static byte[] stringToByteArray(String text)
	{
		byte[] byteArray = new byte[text.length()];
		for (int i=0; i<text.length(); i+=2)
		{
			int z = Integer.decode("0x" + text.substring(i,i+2));			
			byte tmp = (byte) z;
			byteArray[i] = tmp;
		}
		
		byte[] returnByteArray = new byte[text.length()/2];
		int x=0;
		for (int i=0;i<text.length(); i+=2)
		{
			returnByteArray[x] = byteArray[i];
			x+=1;
		}
		return returnByteArray;		
	}
	
	 /**
	  * Print out the given byte array.
	  * @param ausgabeZeichen The byte array.
	  * @param text The text which should print out before the array. 
	  */
	 public static void printOutByteArray(byte[] ausgabeZeichen,String text)
	{		
	   	System.out.println(text);
	               for ( byte d : ausgabeZeichen )
		{		
			if ((Integer.toHexString( d & 0xFF)).toUpperCase().length() < 2)								
				System.out.print("0");
			System.out.print((Integer.toHexString( d & 0xFF)).toUpperCase());
		}
	    System.out.println();
		System.out.println();
	}
	
	 /**
	 * @return The Public Key Object.
	 * @param  modulus The modulus public key.
	 * @param  exponent The exponent public key.
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchProviderException
	 * @throws InvalidKeySpecException
	 */
	public static PublicKey getPubKey(String modulus, String exponent) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException
	{
		KeyFactory keyFactory;
		keyFactory = KeyFactory.getInstance("RSA", "BC");
		
		RSAPublicKeySpec pubKeySpec = new RSAPublicKeySpec(
	              new BigInteger(modulus,16),
	              new BigInteger(exponent,16));
	    RSAPublicKey pubKeyr = (RSAPublicKey)keyFactory.generatePublic(pubKeySpec);
	    return pubKeyr;
	}
}
 
Hi!
Eventuell hilft Dir das:
Some methods in the javax.net.ssl package create certificate objects that are not compatible with the certificate objects in the java.security.cert package. This example implements two methods that convert between the two types of certificate objects.
Code:
// Converts to java.security
    public static java.security.cert.X509Certificate convert(javax.security.cert.X509Certificate cert) {
        try {
            byte[] encoded = cert.getEncoded();
            ByteArrayInputStream bis = new ByteArrayInputStream(encoded);
            java.security.cert.CertificateFactory cf
                = java.security.cert.CertificateFactory.getInstance("X.509");
            return (java.security.cert.X509Certificate)cf.generateCertificate(bis);
        } catch (java.security.cert.CertificateEncodingException e) {
        } catch (javax.security.cert.CertificateEncodingException e) {
        } catch (java.security.cert.CertificateException e) {
        }
        return null;
    }
    
    // Converts to javax.security
    public static javax.security.cert.X509Certificate convert(java.security.cert.X509Certificate cert) {
        try {
            byte[] encoded = cert.getEncoded();
            return javax.security.cert.X509Certificate.getInstance(encoded);
        } catch (java.security.cert.CertificateEncodingException e) {
        } catch (javax.security.cert.CertificateEncodingException e) {
        } catch (javax.security.cert.CertificateException e) {
        }
        return null;
    }

mfg
DocRandom
 
Danke erstmal für die Antwort.
Eigentlich wollte ich das gar nicht über Zertifikate machen. Weist du denn vielleicht wo das Problem bei dem Public Key liegt, weil wenn ich einen Public Key generiere und und diesen dann verwende dann klappt es wunderbar, aber wenn ich meinen eigenen Schlüssel nehme bekomme ich die oben genannte Exception. Selbst wenn ich den Modulus und den Exponent des generierten Keys verwende bekomme ich die Exception. Da frage ich mich was ich da verkehrt mache.
Brauche da dringend Hilfe.
 
Moin!

Leider kann ich Dir im Moment nicht weiterhelfen, das SSL unter JAVA auch für mich noch Neuland ist!
Ich hatte den Artikel nur, weil ich mich demnächst damit auseinandersetzen muß.

mfg
DocRandom
 
lies doch mal beide Schlüssel irgendwie ein und in ne Datei ... hab mal irgendwas von unterschiedlichen Schlüsselgrößen gehört bei RSA... woher stammt denn dein Schlüssel womit wurde der gemacht? Vielleicht da mal gucken, welche Algorithmen die überhaupt verwenden? Evtl. liegen da noch irgendwelche header-daten drin?

nur so ins blaue geschossen 😉
 
Ich habe mal beide Schlüssel mir ausgeben lassen und die sind von der Struktur her identisch. Auch die länge ist identisch. Allerdings wenn ich meine eigene Signatur die ich aus dem File habe mit der zum testen signierten vergleiche, dann sind die unterschiedlich lang.
Vielleicht liegt da der Fehler???????
 
Sorry vergessen:
die Signature aus dem File ist 256 Byte und die zum testen mit sign() erstellte ist 128 Byte. Die Schlüssellänge sind wie gesagt identisch.
 
So, habe mal das PKCS1Padding weggelassen, dann sind die letzten 40 Zeichen der Digest, genau das was ich brauche. DAs klappt aber nur mit den generierten Schlüssel, bei meinen eigenen kommt nur schrott raus.
Also kann eigentlich nur was mit dem anlegen des PublicKeys nicht stimmen.

Kann mir da jemand helfen??
 
Status
Nicht offen für weitere Antworten.

Neue Themen


Zurück
Oben