2016-04-28 11 views
2

Ich versuche die modPow Funktion auf Java Card mit dem eingebauten RSA CryptoSystem zu implementieren. Der Code scheint trivial zu sein, aber ich habe auf Implementierung hingewiesen.Java Card setExponent() Methode schlägt fehl, wenn der Exponent mehr als 10 Bytes hat

Mein Code untill jetzt:

Cipher m_encryptCipherRSA = Cipher.getInstance(Cipher.ALG_RSA_NOPAD, false); // create the cipher 
    RSAPublicKey m_rsaPublicKey = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC,KeyBuilder.LENGTH_RSA_1024,false); // create the public key 
    m_random = RandomData.getInstance(RandomData.ALG_SECURE_RANDOM); 
    m_random.generateData(temp1, (short)0, MODULUS_LENGTH); 
    m_rsaPublicKey.setModulus(temp1,(short)0, MODULUS_LENGTH); //generate modulus 
    m_random.generateData(temp1,(short)0, (short) EXPONENT_LENGTH); 
    m_rsaPublicKey.setExponent(temp1,(short)0, (short)EXPONENT_LENGTH); 

Der Kabeljau ok scheint zu funktionieren, wenn EXPONENT_LENGTH nicht mehr als 10 bytes.The Java Card Ich habe die Dimension der öffentlichen Exponenten begrenzt hat. Jedoch basiert mein Projekt auf Zahlen bis zu 128 Bytes lang. Gibt es eine Möglichkeit, eine generische modpow Funktion basierend auf dieser Hardwarebeschränkung zu erstellen? Gibt es eine andere Möglichkeit, die noch mögliche Potenzierung zu implementieren?

+0

Was passiert, wenn Sie 'EXPONENT_LENGTH> 10' verwenden? Welches Statuswort bekommst du? – vojta

+0

@vojta 6f 00 das ist unbekannter Fehler. – Marga

+0

Fangen Sie die ausgelöste Ausnahme und sagen Sie uns ihren Typ (verwenden Sie den Operator instanceof) und ihren Grund (Ausgabe der Methode getReason()). – vojta

Antwort

1

Ich habe es geschafft, das Problem zu lösen, indem Sie den privaten Exponenten verwenden (der nicht durch das RSA-Kryptosystem eingeschränkt zu sein scheint). Unten ist der Arbeitscode.

public byte[] modPow(byte[] x,short xOffset,short xLength,byte[] y,short yOffset,short yLength) 
{ 
    Util.arrayCopy(y, yOffset, tempBuffer, (short)(Configuration.TEMP_OFFSET_EXPONENT+4), yLength); 
    Util.arrayFillNonAtomic(tempBuffer, Configuration.TEMP_OFFSET_EXPONENT, (byte)4,(byte)0x00); 
    mRsaPrivateKeyModPow.setExponent(tempBuffer,Configuration.TEMP_OFFSET_EXPONENT, (short)(yLength+4)); 
    mRsaCipherModPow.init(mRsaPrivateKeyModPow, Cipher.MODE_DECRYPT); 
    Util.arrayCopy(x,xOffset,tempBuffer, Configuration.TEMP_OFFSET_RSA, Configuration.LENGTH_RSAOBJECT_MODULUS); 
    mRsaCipherModPow.doFinal(tempBuffer,Configuration.TEMP_OFFSET_RSA, (short) (Configuration.LENGTH_RSAOBJECT_MODULUS), tempBuffer,Configuration.TEMP_OFFSET_RSA); 
    mRsaPrivateKeyModPow.clearKey(); 
    return tempBuffer; 
} 
1

Nun habe ich versucht, sowohl RSAPublicKey und RSAPrivateKey für zwei verschiedene Karten, und beide funktionierte gut:

package soqPack; 

import javacard.framework.*; 
import javacard.security.KeyBuilder; 
import javacard.security.RSAPrivateKey; 
import javacard.security.RSAPublicKey; 
import javacard.security.RandomData; 
import javacardx.biometry.BioBuilder; 
import javacardx.crypto.Cipher; 

public class modPowtest extends Applet { 

    //Definition Of INS in APDU command 
    public static final byte INS_MOD_POW = (byte) 0x00; 

    //Switch cases to choose RSA Public key or RSA Private key for ModPow() 
    //P1 in APDU command. 
    public static final byte USE_PUB_KEY = (byte) 0x00; 
    public static final byte USE_PRI_KEY = (byte) 0x01; 

    //Required objects 
    byte[] tempMem; 
    Cipher myCipher; 
    RSAPrivateKey rsaPriKey; 
    RSAPublicKey rsaPubKey; 
    RandomData random; 

    public static void install(byte[] bArray, short bOffset, byte bLength) { 
     new modPowtest(); 
    } 

    protected modPowtest() { 
     myCipher = Cipher.getInstance(Cipher.ALG_RSA_PKCS1, false); 
     rsaPriKey = (RSAPrivateKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PRIVATE, KeyBuilder.LENGTH_RSA_1024, false); 
     rsaPubKey = (RSAPublicKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PUBLIC, KeyBuilder.LENGTH_RSA_1024, false); 
     tempMem = JCSystem.makeTransientByteArray((short) 0x80, JCSystem.CLEAR_ON_DESELECT); 
     random = RandomData.getInstance(RandomData.ALG_PSEUDO_RANDOM); 
     register(); 
    } 

    public void process(APDU apdu) { 
     if (selectingApplet()) { 
      return; 
     } 

     byte[] buffer = apdu.getBuffer(); 
     switch (buffer[ISO7816.OFFSET_INS]) { 
      case INS_MOD_POW: 
       modPow(apdu); 
       break; 
      default: 
       ISOException.throwIt(ISO7816.SW_INS_NOT_SUPPORTED); 
     } 
    } 

    public void modPow(APDU apdu) { 
     byte[] buffer = apdu.getBuffer(); 
     switch (buffer[ISO7816.OFFSET_P1]) { 
      case USE_PUB_KEY: 
       random.generateData(tempMem, (short) 0x00, (short) 0x80); 
       rsaPubKey.setModulus(tempMem, (short) 0x00, (short) 0x80); 
       random.generateData(tempMem, (short) 0x00, (short) 0x03); 
       rsaPubKey.setExponent(tempMem, (short) 0x00, (short) 0x03); 
       break; 
      case USE_PRI_KEY: 
       random.generateData(tempMem, (short) 0x00, (short) 0x80); 
       rsaPriKey.setModulus(tempMem, (short) 0x00, (short) 0x80); 
       random.generateData(tempMem, (short) 0x00, (short) 0x03); 
       rsaPriKey.setExponent(tempMem, (short) 0x00, (short) 0x03); 
       break; 
      default: 
       ISOException.throwIt(ISO7816.SW_INCORRECT_P1P2); 
     } 

    } 
} 

Arbeiten wie folgt:

Download Cap begin... 
Download Cap successful. 
Install Applet begin... 
Install Applet successful. 
Select Applet begin... 
Select Applet successful. 

Send: 00 00 00 00 00 
Recv: 90 00 

Send: 00 00 01 00 00 
Recv: 90 00 

Update: (Related Ihre neue Frage in den Kommentaren und here):

Ich habe auch, den Wert von tempMem[0] kurz vor den setModulus und setExponent Methoden 0x69, und es funktioniert immer noch in Ordnung.

+2

Ich lese, dass 'setExponent()' kann fehlschlagen, wenn Die Größe des Exponenten ist größer als 4 Bytes. Aus der Orakeldokumentation habe ich folgendes gefunden: "Alle Implementierungen müssen Exponentenwerte von bis zu 4 Bytes Länge unterstützen. Implementierungen können auch Exponentenwerte von mehr als 4 Bytes Länge unterstützen. Hier ist der [link] (http://www.win.tue.nl/pinpasjc/docs/apis/jc222/javacard/security/RSAPublicKey.html). – Marga

+0

Ich beginne [hier] (http://stackoverflow.com/questions/36966764/rsa-cipher-java-card-error) mit dem neuen Problem.Es scheint mir ein Problem mit dem Modul vallue.Ich denke, es ist weniger als der x-Wert von RSA und der Algorithmus schlägt fehl. – Marga