我想在Swift 3中转换以下base64编码的String
:
dfYcSGpvBqyzvkAXkdbHDA==
等同于String
:
uöHjo¬³¾@‘ÖÇ
以下网站的工作非常好:
http://www.motobit.com/util/base64-decoder-encoder.asp
http://www.utilities-online.info/base64/#.WG-FwrFh2Rs
PHP的函数base64_decode
也是如此。此函数的documentation表示:
如果输入包含base64外部的字符,则返回FALSE 字母表。
但我无法在Swift 3中做同样的事情。以下代码也不能完成这项工作:
func convertBase64ToNormalString(base64String:String)->String!{
let decodedData = Data(base64Encoded: base64String, options: Data.Base64DecodingOptions())
let bytes = decodedData?.bytes
return String(bytes: bytes, encoding: NSUTF8StringEncoding)
}
以下是有关我需要将base64字符串转换为字符串的原因的上下文信息: 我的Php开发人员希望我发送所有使用AES算法加密的API参数值。为此,我使用的是this lib。 他给了我十六进制格式的AES密钥(我在我的last question中提到)和iv在base64(上面给出)中,他指示我在使用之前解码这个base64密钥,因为他在PHP代码中也做了同样的事情。这是他的加密和解密PHP代码:
function encryptParamAES($plaintext, $encryptionEnabled = true) {
if (! $encryptionEnabled) {
return $plaintext;
}
// --- ENCRYPTION ---
// Constants =========================================================
// the key should be random binary, use scrypt, bcrypt or PBKDF2 to
// convert a string into a key
// key is specified using hexadecimal
$key = pack ( 'H*', "dcb04a9e103a5cd8b53763051cef09bc66abe029fdebae5e1d417e2ffc2a07a4" );
// create a random IV to use with CBC encoding
$iv_size = 16;
$iv = base64_decode ( "dfYcSGpvBqyzvkAXkdbHDA==" );
// End Of constants ===================================================
// echo "IV: " . base64_encode ( $iv ) . "\n<br>";
// echo "IV Size: " . $iv_size . "\n<br>";
// show key size use either 16, 24 or 32 byte keys for AES-128, 192
// and 256 respectively
// $key_size = strlen ( $key );
// echo "Key size: " . $key_size . "\n<br><br>";
// creates a cipher text compatible with AES (Rijndael block size = 128)
// to keep the text confidential
// only suitable for encoded input that never ends with value 00h
// (because of default zero padding)
$ciphertext = mcrypt_encrypt ( MCRYPT_RIJNDAEL_128, $key, $plaintext, MCRYPT_MODE_CBC, $iv );
// prepend the IV for it to be available for decryption
$ciphertext = $iv . $ciphertext;
// encode the resulting cipher text so it can be represented by a string
$ciphertext_base64 = base64_encode ( $ciphertext );
return $ciphertext_base64;
}
function decryptParamAES($ciphertext_base64, $encryptionEnabled = true) {
if (! $encryptionEnabled) {
return $ciphertext_base64;
}
// --- DECRYPTION ---
// Constants =========================================================
// the key should be random binary, use scrypt, bcrypt or PBKDF2 to
// convert a string into a key
// key is specified using hexadecimal
$key = pack ( 'H*', "dcb04a9e103a5cd8b53763051cef09bc66abe029fdebae5e1d417e2ffc2a07a4" );
// create a random IV to use with CBC encoding
$iv_size = 16;
$iv = base64_decode ( "dfYcSGpvBqyzvkAXkdbHDA==" );
// End Of constants ===================================================
$ciphertext_dec = base64_decode ( $ciphertext_base64 );
// retrieves the IV, iv_size should be created using mcrypt_get_iv_size()
$iv_dec = substr ( $ciphertext_dec, 0, $iv_size );
// retrieves the cipher text (everything except the $iv_size in the front)
$ciphertext_dec = substr ( $ciphertext_dec, $iv_size );
// may remove 00h valued characters from end of plain text
$plaintext_dec = mcrypt_decrypt ( MCRYPT_RIJNDAEL_128, $key, $ciphertext_dec, MCRYPT_MODE_CBC, $iv_dec );
return rtrim ( $plaintext_dec );
}
我刚刚看到这个PHP代码,并想知道为什么他不使用$ iv作为mcrypt_decrypt
函数的最后一个参数!会更新你的。但问题仍然存在,PHP函数base64_decode
不会为上述base64字符串返回FALSE
!
我通过终端命令自己测试了这个功能:php test.php
。这里test.php包含以下代码:
<?php
$iv = base64_decode ( "dfYcSGpvBqyzvkAXkdbHDA==" );
echo $iv;
?>
输出结果为:u?Hjo???@???
答案 0 :(得分:1)
查看修改后的问题,您尝试使用此base-64字符串,并将其用作AES算法中的iv
。我可以理解为什么您想知道如何将Data
转换为String
,但您不应该这样做。是的,有一个AES
的格式,期望iv
为字符串。但还有另一个版本需要Array<UInt8>
。所以,就像MartinR在his answer to your other question中说的那样,构建一个UInt8
的数组,就像这样:
let iv = Array(Data(base64Encoded: "dfYcSGpvBqyzvkAXkdbHDA==")!)
结果iv
是Array<UInt8>
(也称为[UInt8]
)。您可以将其与AES
功能一起使用。
我最初关于将Data
个对象转换为UTF8字符串的讨论如下。但关键信息是你不应该试图这样做。只需构建UInt8
数组,并将其与库AES
函数一起使用。
查看您的其他问题(Convert hex-encoded String to String in Swift 3),您在评论中透露您正在处理AES密钥。我怀疑我们在这里处理类似的问题(尽管那是32字节的数据,这里我们有16个字节)。
最重要的是,我建议你完全放弃这个“如何获得在这个base-64字符串中捕获的数据的字符串表示”查询行。如果它是加密密钥(或某些令牌或其他),请不要试图将其表示为字符串。 (这是base-64的 raison d'être,用于创建非字符串数据的可传输字符串表示。)
我建议你退后一步,描述你想要解决的更广泛的问题。停止尝试从这些二进制有效负载中创建字符串。在您的代码段中,您已成功从base-64字符串创建Data
。我认为,真正的问题不是“我现在如何从中获取字符串?”而是“我该怎么做Data
?”
如果没有关于您获取此数据的位置及其用途的更多背景信息,我们无法回答该问题。
顺便说一下,我对你问题的原始答案如下。
问题是base-64字符串转换为16字节的数据,其十六进制表示为
75f61c48 6a6f06ac b3be4017 91d6c70c
但是那个有效载荷是无效的UTF8字符串。第三个字节1c
与UTF8字符串不一致。如果你查看definition of UTF8,它会说如果一个字节在f6
- fb
范围内,第二个字节是,那个字符由以下两个字符组成字节,两者都应在21
- 7e
或a0
- ff
范围内,1c
不是。
因此,这根本不是有效的UTF8字符串。显然,您正在使用的那些网站没有正常检测/处理无效的UTF8字符串。
也许这个base-64字符串中的数据是使用不同的编码从字符串转换而来的。或者,它可能根本不是一个字符串。并非所有二进制有效负载都具有干净的字符串表示坦率地说,这就是为什么我们首先使用base-64表示,以提出一个不是字符串的数据blob的文本表示。
如果您提供有关此base-64字符串中包含的数据来源的更多信息,我们可能会为您提供进一步的建议。
答案 1 :(得分:0)
我为同样的情况找到了很好的解决方案。看https://github.com/kylef/JSONWebToken.swift/blob/master/Sources/Base64.swift
我只是用于检查JWT的库,但你可以使用执行base64decode的func。