0

問題があります。php ページから返されたデータを復号化すると、文字列の長さが 16 未満の場合、文字 \0 が文字列に追加されます。元の文字列は次のとおりです: 100000065912248 この関数で暗号化された文字列を復号化します。

#define FBENCRYPT_ALGORITHM     kCCAlgorithmAES128
#define FBENCRYPT_BLOCK_SIZE    kCCBlockSizeAES128
#define FBENCRYPT_KEY_SIZE      kCCKeySizeAES256

+ (NSData*)decryptData:(NSData*)data key:(NSData*)key iv:(NSData*)iv;
{
    NSData* result = nil;

    // setup key
    unsigned char cKey[FBENCRYPT_KEY_SIZE];
    bzero(cKey, sizeof(cKey));
    [key getBytes:cKey length:FBENCRYPT_KEY_SIZE];

    // setup iv
    char cIv[FBENCRYPT_BLOCK_SIZE];
    bzero(cIv, FBENCRYPT_BLOCK_SIZE);
    if (iv) {
        [iv getBytes:cIv length:FBENCRYPT_BLOCK_SIZE];
    }

    // setup output buffer
    size_t bufferSize = [data length] + FBENCRYPT_BLOCK_SIZE;
    void *buffer = malloc(bufferSize);

    int length = [data length];

    // do decrypt
    size_t decryptedSize = 0;
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,
                                          FBENCRYPT_ALGORITHM,
                                          0,
                                          cKey,
                                          FBENCRYPT_KEY_SIZE,
                                          cIv,
                                          [data bytes],
                                          [data length],
                                          buffer,
                                          bufferSize,
                                          &decryptedSize);

    if (cryptStatus == kCCSuccess) {
        result = [NSData dataWithBytesNoCopy:buffer length:decryptedSize];
    } else {
        free(buffer);
        NSLog(@"[ERROR] failed to decrypt| CCCryptoStatus: %d", cryptStatus);
    }

    return result;
}

関数にnilの「iv」パラメーターを送信し、関数で「cIv」を使用した後、これが含まれます: 文明の説明

結果は正確ですが、string の長さは 15 ではなく 16 です (string: 100000065912248)。実際、最後の文字は \0 です。

なんで?どうすれば解決できますか?

編集:

PHP 暗号化機能:

function encrypt($plaintext) {

    $key = 'a16byteslongkey!a16byteslongkey!';

    $base64encoded_ciphertext = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC));
    $base64encoded_ciphertext = trim($base64encoded_ciphertext);

    return $base64encoded_ciphertext;
}
4

3 に答える 3

2

AES はブロック暗号であり、長さ 128 ビット (16 バイト) のブロックを暗号化/復号化します。したがって、データがブロック サイズでない場合は、パディングを追加する必要があります。最も人気があり、Apple によってサポートされているのは PKCS7 です。

PHP とのインターフェースでは、パディングと可能な base64 エンコーディングを考慮する必要があります。

解決策は、PHP と iOS の両側で同じパディングを使用することです。

AES は常に 16 バイトで動作します。オプションはありません。つまり、15 バイトの場合、1 バイトを追加する必要があります。これがパディングです。私が理解していることから (PHP 暗号化についてはあまり詳しくありません)、PHP は真の PCKS7padding を行わないため、自分でパディングするのが最善です。ウィキペディアで PKCS7 を参照してください。

于 2013-02-17T20:51:08.123 に答える
0

文字列のみを操作する場合は、ゼロのパディング(デフォルト)で問題ないはずですが、相互運用性の理由からのみ、PKCS#7のパディングをお勧めします。

ゼロのパディングでは、平文は00値のバイトでパディングされますが、必要な場合に限ります。これは、常に展開されるPKCS#7パディングとは異なります。復号化後、復号化後に結果の平文trimで関数を使用できます。次に、元の文字列を取得する必要があります。

関数によって削除された文字で終わる可能性があるため、これは明らかにバイナリデータではtrim機能しません。trimPHPでは00バイトを削除するように見えることに注意してください。00多くのランタイムでそのように扱われていても、これは与えられたものではなく、公式には空白ではありません。

于 2013-02-18T22:58:24.360 に答える