PHPで文字列を暗号化して、Android/iOSで復号化する

PHPで暗号化した文字列をAndroid/iOSで復号化する方法。

PHPで文字列を暗号化します。

暗号化した文字列と、暗号化キー・初期ベクトルをBASE64エンコードしてAndroidとiOSに渡します。

<?php
// 暗号化する文字列
$text = 'AES128はブロック長128bit(16byte)、鍵長128bit(16byte)のブロック暗号です。';
$cipher = 'AES-128-CBC';
$len = openssl_cipher_iv_length($cipher);
$key = openssl_random_pseudo_bytes($len); // 暗号化キー
$iv = openssl_random_pseudo_bytes($len); // 初期ベクトル
$options = 0;
$encryptedText = openssl_encrypt($text, $cipher, $key, $options, $iv);
if ($encryptedText == FALSE) {
    echo '失敗しました。';
} else {
    echo 'Base64エンコードした暗号化文字列<br>';
    echo $encryptedText . '<br><br>';
    echo 'Base64エンコードされた暗号化キー<br>';
    echo base64_encode($key) . '<br><br>';
    echo 'Base64エンコードされた初期ベクトル<br>';
    echo base64_encode($iv) . '<br><br>';

    echo openssl_decrypt($encryptedText, $cipher, $key, $options, $iv);
}

iOSで復号化します。

/**
 * 暗号化された文字列を復号化する
 * @param base64Source BASE64エンコードされた暗号化文字列
 * @param base64Key BASE64エンコードされた暗号化キー
 * @param base64Iv BASE64エンコードされた初期ベクトル
 * @return 復号化された文字列
 */
- (NSString*)decrypt:(NSString*)base64Source key:(NSString*)base64Key iv:(NSString*)base64Iv
{
    NSData* sourceData = [[NSData alloc] initWithBase64EncodedString:base64Source options:NSDataBase64DecodingIgnoreUnknownCharacters];
    NSData* keyData = [[NSData alloc] initWithBase64EncodedString:base64Key options:NSDataBase64DecodingIgnoreUnknownCharacters];
    NSData* ivData = [[NSData alloc] initWithBase64EncodedString:base64Iv options:NSDataBase64DecodingIgnoreUnknownCharacters];

    CCCryptorRef ref;
    CCCryptorStatus status = CCCryptorCreate(kCCDecrypt, kCCAlgorithmAES, kCCOptionPKCS7Padding, [keyData bytes], kCCKeySizeAES128, [ivData bytes], &ref);
    if (status != kCCSuccess) {
        [NSException raise:@"CCCryptorCreate Error" format:@"%@",[self getStatusText:status]];
    }

    NSUInteger length = [sourceData length];
    size_t dataOutAvailable = length + kCCBlockSizeAES128;

    void* response = malloc(dataOutAvailable*sizeof(size_t));
    size_t updateResultLength = 0;
    status = CCCryptorUpdate(ref, [sourceData bytes], [sourceData length], response, dataOutAvailable, &updateResultLength);
    if (status != kCCSuccess) {
        [NSException raise:@"CCCryptorUpdate Error" format:@"%@",[self getStatusText:status]];
    }

    size_t finalResultLength = 0;
    status = CCCryptorFinal(ref, response + updateResultLength, dataOutAvailable, &finalResultLength);
    if (status != kCCSuccess) {
        CCCryptorRelease(ref);
        [NSException raise:@"CCCryptorFinal Error" format:@"%@",[self getStatusText:status]];
    }

    NSUInteger len = (updateResultLength + finalResultLength);
    NSData* decryptedData = [NSData dataWithBytes:(const void *)response length:len];
    CCCryptorRelease(ref);
    return [[NSString alloc] initWithData:decryptedData encoding:NSUTF8StringEncoding];
}

Androidで復号化します。

/**
    * Base64エンコードされた暗号化された文字列を復号化する
    * @param base64Source Base64エンコードされた暗号化された文字列
    * @param base64Key Base64エンコードされたキー文字列
    * @param base64Iv Base64エンコードされたIV文字列
    * @return 復号化した文字列
    */
private String decrypt(String base64Source, String base64Key, String base64Iv) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    byte[] sourceBytes = Base64.decode(base64Source, Base64.DEFAULT);
    byte[] keyBytes = Base64.decode(base64Key, Base64.DEFAULT);
    byte[] ivBytes = Base64.decode(base64Iv, Base64.DEFAULT);

    SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
    IvParameterSpec ivParameterSpec = new IvParameterSpec(ivBytes);
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
    byte[] decryptedBytes = cipher.doFinal(sourceBytes);
    return new String(decryptedBytes);
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください