iOS y Android cifrado AES (n UINT en Java)

Eric:

Todos,

Soy nuevo en el cifrado así que no estoy seguro de toda la información que necesito compartir para obtener ayuda; pero voy a editar esta pregunta a medida que aprendo más sobre cómo solicitar también esta pregunta :)

Estoy realizando el cifrado AES en tanto un iOS y una aplicación para Android que se comunican a través de Bluetooth a un dispositivo. Estoy utilizando el cifrado AES CTR y se ejecuta por completo y funcional en IOS. El problema que estoy corriendo en es que cuando convierto elementos, como Mis IV a una matriz de bytes; bytes de Java están firmados y bytes rápidos están sin firmar así que mientras yo puedo cifrar y descifrar mi cadena en Java; se trata de un resultado diferente de lo que me gustaría ver en IOS.

¿Cómo están las demás personas se ocupan de este tema unsigned int? Siento que hay Tiene que haber alguna cosa recta de avance que estoy haciendo mal. Realmente no estoy seguro de lo que el código para enviar. Para android que estoy usando cadena hexadecimal a las funciones de conversión de bytes que encontré aquí en desbordamiento de pila y están trabajando correctamente ... sólo están firmados sin firmar en lugar de lo que los valores son diferentes de las matrices de bytes sin signo en iOS.

IOS Implementación:

let aesPrivateKey = "********************************"

print("MacAddress:-> \(macAddress)")

var index = 0

let aesPrivateKeyStartIndex = aesPrivateKey.startIndex
let macAddressStartIndex = macAddress.startIndex

//Perform an XOR to get the device key
var deviceKeyArray: Array<Character> = Array(repeating: "?", count: 32)
for _ in macAddress {
    let nextPrivateKeyIndex = aesPrivateKey.index(aesPrivateKeyStartIndex, offsetBy: index)
    let nextMacAddressIndex = macAddress.index(macAddressStartIndex, offsetBy: index)

    let nextPrivateKeyString = String(aesPrivateKey[nextPrivateKeyIndex])
    let nextMacAddressString = String(macAddress[nextMacAddressIndex])

    let nextPrivateKeyByte = Int(nextPrivateKeyString, radix: 16)
    let nextMacAddressByte = Int(nextMacAddressString, radix: 16)

    let nextCombinedByte = nextPrivateKeyByte! ^ nextMacAddressByte!

    let nextCombinedString = nextCombinedByte.hexString

    deviceKeyArray[index] = nextCombinedString[nextCombinedString.index(nextCombinedString.startIndex, offsetBy: 1)]

    index+=1
}
while(index < 32) {

    let nextPrivateKeyIndex = aesPrivateKey.index(aesPrivateKeyStartIndex, offsetBy: index)
    deviceKeyArray[index] = aesPrivateKey[nextPrivateKeyIndex]
    index += 1
}

//Convert the device key to a byte array
let deviceKey = "0x" + String(deviceKeyArray)
let deviceKeyByte = Array<UInt8>(hex: deviceKey)

//Convert the password to a byte array
let passwordByte : Array<UInt8> = password.bytes

//Convert the initialization vector to a byte array
let aesIVHex = "0x" + AESIV
let aesIVByte = Array<UInt8>(hex: aesIVHex)

//Encrypt the password
var encrypted = [Unicode.UTF8.CodeUnit]()
do{
    encrypted = try AES(key: deviceKeyByte, blockMode: CTR(iv: aesIVByte)).encrypt(passwordByte)
}
catch{
    print(error)
}

print("The Encrypted Password Data: \(encrypted)")

let encryptedData = encrypted.toHexString()

//Write password to bluetooth and check result
UserDefaultUtils.setObject(encryptedData as AnyObject, key: userDefaults.password)
DeviceLockManager.shared().isEncrypted = false.
DeviceLockManager.share().setVerifyPasswordForDevice(isGunboxDevice:true)

aplicación Android:

System.out.println("ble_ Password:"+str_password+"\nble_ AesKey:"+aesDeviceKey+"\nble_ AesIV:"+aesIV);

byte[] encryptedData = encrypt(
        str_password.getBytes(),
        Utility.getInstance().hexStringToByteArray(aesDeviceKey),
        Utility.getInstance().hexStringToByteArray(aesIV));

String encryptedPassword = Utility.getInstance().bytesToHexString(encryptedData);
System.out.println("ble_ AES Encrypted password " + encryptedPassword);
byte[] decryptedData = decrypt(encryptedData, aesDeviceKey.getBytes(), aesIV.getBytes());
System.out.println("ble_ Cipher Decrypt:"+new String(decryptedData));

//Write password to bluetooth and check result
deviceManager.writePassword(encryptedPassword);
Utility.getInstance().sleep(100);
deviceManager.readPasswordResult();

Todos los valores de entrada coinciden exactamente hasta que llame a la función: hextStringtoByteArray. En este punto, el IOS byte matrices están sin firmar y se firman las matrices de bytes androide.

Aquí es que la función de referencia:

public static byte[] hexStringToByteArray(String s){
    byte[] b = new byte[s.length() / 2];
    for (int i = 0; i < b.length; i++) {
        int index = i * 2;
        int v = Integer.parseInt(s.substring(index, index + 2), 16);
        b[i] = (byte) v;
    }
    return b;
}

Muestra de Array IV Byte:

iOS vs Android:

43, 34, 95, 101, 57, 150, 75, 100, 250, 178, 194, 70, 253, 236, 92, 70

43, 34, 95, 101, 57, -106, 75, 100, -6, -78, -62, 70, -3, -20, 92, 70

n247s:

Usted puede notar una diferencia entre las dos matrices impresas porque java por defecto es la de un byte como un valor con signo. Pero en realidad los que son realmente iguales. Para que quede más claro que voy a añadir una pequeña mesa con los últimos 5 valores de la matriz ejemplo IV que ya ha proporcionado.

|----------------------------------------|
| hex      |  46 |  FD |  EC |  5C |  46 |
|----------------------------------------|
| unsigned |  70 | 253 | 236 |  92 |  70 |
|----------------------------------------|
| signed   |  70 | -3  | -20 |  92 |  70 |
|----------------------------------------|

Por lo que son en realidad la misma (poco aconsejable), solamente impresa a pintadas, ya que se interpretan como valores diferentes. Si desea asegurarse de que todo son correctos, sugeriría mirar algunos números con una calculadora en el modo de programación. Por lo general, hay una manera de ajustar la longitud de byte / palabra para que pueda jugar con firmado vs interpretación sin firma del mismo valor hexadecimal (que también debería ser un poco representación del valor).

Como una alternativa I encontré un pequeño sitio web que contiene una firmaron vs tipo unsigned bits / convertidor hexagonal, lo que hará el truco también. (asegúrese de seleccionar ya sea de tipo char, de lo contrario los valores con signo serán incorrectos)


Así, en el IV-bytes parte del código que no debería haber ningún problema. Puede haber uno sin embargo, cuando se crea la cadena utilizando sólo un byte-array como parámetro. EI:

byte[] decryptedData = decrypt(encryptedData, aesDeviceKey.getBytes(), aesIV.getBytes());
System.out.println("ble_ Cipher Decrypt:" + new String(decryptedData));

Dado que muy probablemente el juego de caracteres usado no es UTF-8. (se puede determinar que llamando Charset#defaultCharset, y comprobar su valor). La alternativa sería la siguiente:

new String(decryptedData, StandardCharsets.UTF_8)

o:

new String(decryptedData, "UTF-8");

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=208267&siteId=1
Recomendado
Clasificación