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
Die Operations Klasse
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;
}
}