2016-07-22 4 views
5

Ich versuche, einen ISO-0-Pinblock mit dem Codenameon BouncyCastle lib zu verschlüsseln. Die Methoden I, dies zu erreichen, verwenden, ist wie folgt:Daten nicht Blockgröße in Codenameon ausgerichtet BouncyCastle (Kein Padding)

private static byte[] performEncrypt(byte[] key, String plainText, boolean padding) { 
    byte[] ptBytes = plainText.getBytes(); 

    BufferedBlockCipher cipher; 
    if (padding) { 
     cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new DESedeEngine())); 
    } else { 
     cipher = new BufferedBlockCipher(new CBCBlockCipher(new DESedeEngine())); 
    } 
    cipher.init(true, new KeyParameter(key)); 
    byte[] rv = new byte[cipher.getOutputSize(ptBytes.length)]; 
    int oLen = cipher.processBytes(ptBytes, 0, ptBytes.length, rv, 0); 
    try { 
     cipher.doFinal(rv, oLen); 
    } catch (CryptoException ce) { 
     LoggingUtil.error(TAG, ce, "Unexpected Exception"); 
    } 
    return rv; 
} 

private static String createIso0PinBlock(String pin, String number) { 
    ... 
} 

private static String getPaddedData(String data, byte padCharacter) { 
    String paddedData = ByteUtil.pad(data, (char) padCharacter, 8).toString(); 
    return paddedData; 
} 

public static String createPinBlockAndEncrypt(String pin, String number) { 
    LoggingUtil.debug("SecurityUtil", "CREAT PIN BLOCK AND ENCRYPT.. PIN: " + pin + " NUMBER: " + number); 
    String pb = createIso0PinBlock(pin, number.substring(0, number.length() - 1)); 
    LoggingUtil.debug("SecurityUtil", "PINBLOCK: " + pb); 
    String padded = getPaddedData(pb, (byte) 0x00); 
    LoggingUtil.debug("SecurityUtil", "PADDED: " + padded); 
    byte[] encrypted = performEncrypt(Hex.decode(KEY.getBytes()), new String(ByteUtil.hex2byte(padded)), false); 
    return ByteUtil.byte2hex(encrypted); 
} 

In ByteUtil:

public static StringBuilder pad(String data, char padCharacter, int multiplier) { 
    StringBuilder text = new StringBuilder(); 
    text.append(data); 
    while (text.length() % multiplier != 0) { 
     text.append(padCharacter); 
    } 
    return text; 
} 

Beispiel Logausgaben zu geben:

[SecurityUtil] CREAT PIN BLOCK AND ENCRYPT.. PIN: 2255 NUMBER: 6284734104205417486 
[SecurityUtil] PINBLOCK: 042214FBDFABE8B7 
[SecurityUtil] PADDED: 042214FBDFABE8B7 

Wenn ich laufen diese durch eine public static void main Verfahren funktioniert es wie erwartet, aber wenn ich das für Android über Codenameone erstelle, erhalte ich den folgenden Fehler in logcat:

Trotz der gepolsterten Pinblock 16 Länge (ein Vielfaches von 8).

Jede Hilfe zu diesem Thema wäre willkommen.

Antwort

2

Verschlüsselung arbeitet auf binären Daten und Ihr Stimmstock ist binären, so ist es auf diese Weise zu halten.

Wenn performEncrypt(..) Aufruf Sie Ihre hex codiert Stimmstock in einen String konvertieren mit new String(ByteUtil.hex2byte(padded)), und im Inneren performEncrypt(...) Sie es in ein Byte-Array konvertieren mit byte[] ptBytes = plainText.getBytes();. Das Problem dabei ist, dass nicht alle Byte-Sequenzen richtig hin und her durch eine Zeichenfolge zugeordnet werden können, und Sie können mit unterschiedlichen Daten am Ende und sogar unterschiedliche Länge usw. take a look here

ändern Sie Ihre Unterschrift von Ihnen performEncrypt(..) zu:

private static byte[] performEncrypt(byte[] key, byte[] plainText, boolean padding) { 

und vermeiden Sie die Umwandlung durch einen String insgesamt.

+0

Große Antwort. Ich würde vermeiden, Strings für binäre Daten in Codename One zu verwenden, da wir Strings nativen Strings z. auf iOS und sie haben möglicherweise leichte Verhaltensabweichungen in einigen extremen Randfällen. Z.B. Wir hatten ein Problem bei der Integration von Zip-Unterstützung https://www.codenameone.com/blog/zip-and-toast.html –

Verwandte Themen