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);
}