Tengo una aplicación que necesita codificar algunos datos usando AES/CBC/sin relleno. La aplicación también está portada en Android. Allí, la codificación se realiza de esta manera:cifrado iOS AES128/CBC/nopadding ¿por qué no funciona?
byte[] encodedKey = getKey();
SecretKeySpec skeySpec = new SecretKeySpec(encodedKey, "AES");
AlgorithmParameterSpec paramSpec = new IvParameterSpec(initializationVector);
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, paramSpec);
int blockSize = cipher.getBlockSize();
int diffSize = decrypted.length % blockSize;
System.out.println("Cipher size: " + blockSize);
System.out.println("Current size: " + decrypted.length);
if (diffSize != 0) {
diffSize = blockSize - diffSize;
byte[] oldDecrypted = decrypted;
decrypted = new byte[decrypted.length + diffSize];
System.arraycopy(oldDecrypted, 0, decrypted, 0, oldDecrypted.length);
for (int i = 0; i < diffSize; i++) {
decrypted[i + oldDecrypted.length] = " ".getBytes()[0];
}
System.out.println("New size: " + decrypted.length);
}
return cipher.doFinal(decrypted);
la initializationVector se ve así:
private byte[] initializationVector = new byte[] { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
en IOS tengo algo como esto para el cifrado:
- (NSData *)AES128EncryptWithKey:(NSString *)key
{
// 'key' should be 16 bytes for AES128, will be null-padded otherwise
char keyPtr[kCCKeySizeAES128+1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt,
kCCAlgorithmAES128,
0x0000,
keyPtr,
kCCKeySizeAES128,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer); //free the buffer;
return nil;
}
el método descrito anteriormente es parte de una categoría sobre NSData. el método se llama así:
NSData *data = [@"4915200456727" dataUsingEncoding:NSUTF8StringEncoding];
NSData *cipher = [data AES128EncryptWithKey:@"@x#zddXekZerBBw6"];
NSString *ecriptedString = [NSString stringWithFormat:@"%.*s", [cipher length], [cipher bytes]];
el problema que tengo es que no recibo los mismos datos cifrados en iOS y Android. En iOS, los datos cifrados tienen 0 bytes de longitud.
¿Podría dar algún consejo sobre cómo cifrar una cadena utilizando AES128 con CBC y sin relleno y tal vez un ejemplo?
Gracias
Los esquemas de relleno no existen para nada. Si sus datos simples finalizan con el mismo valor que el byte de relleno, su propio esquema fallará. En su lugar, debe usar el relleno PKCS # 5/PKCS # 7. Dependiendo de su necesidad, también debería tener la protección de integridad agregada (encriptación del modo AESCMAC, HMAC o GCM). –
el problema es que el lado del servidor ya está implementado usando AES128/CBC/sin relleno y no se modificará para aceptar el relleno. Sé que el relleno no existe para nada, pero en este caso la posibilidad de que los datos necesarios para ser encriptados terminará con el byte de relleno es realmente pequeña a 0. –
OK, está bien entonces, pero tenga en cuenta: un millón una oportunidad tiene éxito nueve veces de cada diez (Terry Pratchett). Asegúrese de documentar esta "característica". –