すべて、
私は必ず私が助けを得るための共有に必要なすべての情報がないんだので、私は、暗号化に新しいです。私はよくこの質問をする方法についての詳細を学ぶとして、私はこの質問を編集します:)
私は、iOSデバイスにBluetooth経由で通信するAndroidアプリの両方でAES暗号化を行っております。私は、AES CTR暗号化を使用していますし、それは完全に実装およびiOSの機能です。私はに実行している問題は、私はバイト配列に、このような私のIVなどの項目を変換する場合ということです。Javaのバイトが署名されていると私はJavaの上で私の文字列を暗号化および復号化することができますしながら、迅速なバイトがその符号なしています。それは私がiOSの中で見るものとは異なる結果です。
どのように他の人がこのunsigned int型の問題を扱っていますか?私が間違ってやっているいくつかのストレートフォワードなものがあるように持っているような気がします。私は実際にポストしてくださいどのようなコードではありませんよ。値はiOSの符号なしバイト配列とは異なりますので、私は、スタックオーバーフローの上にここで見つけるバイト変換関数に16進文字列を使用していますし、それらが正しく動作しているAndroid用...彼らはただの代わりに、符号なしログインしています。
iOSの実装:
let aesPrivateKey = "********************************"
print("MacAddress:-> \(macAddress)")
var index = 0
let aesPrivateKeyStartIndex = aesPrivateKey.startIndex
let macAddressStartIndex = macAddress.startIndex
//Perform an XOR to get the device key
var deviceKeyArray: Array<Character> = Array(repeating: "?", count: 32)
for _ in macAddress {
let nextPrivateKeyIndex = aesPrivateKey.index(aesPrivateKeyStartIndex, offsetBy: index)
let nextMacAddressIndex = macAddress.index(macAddressStartIndex, offsetBy: index)
let nextPrivateKeyString = String(aesPrivateKey[nextPrivateKeyIndex])
let nextMacAddressString = String(macAddress[nextMacAddressIndex])
let nextPrivateKeyByte = Int(nextPrivateKeyString, radix: 16)
let nextMacAddressByte = Int(nextMacAddressString, radix: 16)
let nextCombinedByte = nextPrivateKeyByte! ^ nextMacAddressByte!
let nextCombinedString = nextCombinedByte.hexString
deviceKeyArray[index] = nextCombinedString[nextCombinedString.index(nextCombinedString.startIndex, offsetBy: 1)]
index+=1
}
while(index < 32) {
let nextPrivateKeyIndex = aesPrivateKey.index(aesPrivateKeyStartIndex, offsetBy: index)
deviceKeyArray[index] = aesPrivateKey[nextPrivateKeyIndex]
index += 1
}
//Convert the device key to a byte array
let deviceKey = "0x" + String(deviceKeyArray)
let deviceKeyByte = Array<UInt8>(hex: deviceKey)
//Convert the password to a byte array
let passwordByte : Array<UInt8> = password.bytes
//Convert the initialization vector to a byte array
let aesIVHex = "0x" + AESIV
let aesIVByte = Array<UInt8>(hex: aesIVHex)
//Encrypt the password
var encrypted = [Unicode.UTF8.CodeUnit]()
do{
encrypted = try AES(key: deviceKeyByte, blockMode: CTR(iv: aesIVByte)).encrypt(passwordByte)
}
catch{
print(error)
}
print("The Encrypted Password Data: \(encrypted)")
let encryptedData = encrypted.toHexString()
//Write password to bluetooth and check result
UserDefaultUtils.setObject(encryptedData as AnyObject, key: userDefaults.password)
DeviceLockManager.shared().isEncrypted = false.
DeviceLockManager.share().setVerifyPasswordForDevice(isGunboxDevice:true)
Androidの実装:
System.out.println("ble_ Password:"+str_password+"\nble_ AesKey:"+aesDeviceKey+"\nble_ AesIV:"+aesIV);
byte[] encryptedData = encrypt(
str_password.getBytes(),
Utility.getInstance().hexStringToByteArray(aesDeviceKey),
Utility.getInstance().hexStringToByteArray(aesIV));
String encryptedPassword = Utility.getInstance().bytesToHexString(encryptedData);
System.out.println("ble_ AES Encrypted password " + encryptedPassword);
byte[] decryptedData = decrypt(encryptedData, aesDeviceKey.getBytes(), aesIV.getBytes());
System.out.println("ble_ Cipher Decrypt:"+new String(decryptedData));
//Write password to bluetooth and check result
deviceManager.writePassword(encryptedPassword);
Utility.getInstance().sleep(100);
deviceManager.readPasswordResult();
hextStringtoByteArray:私は関数を呼び出すまで、すべての入力値が正確に一致します。この時点で、IOSのバイト配列は、符号なしであり、Androidのバイト配列は、署名されています。
ここでは、参照のためにその機能は次のとおりです。
public static byte[] hexStringToByteArray(String s){
byte[] b = new byte[s.length() / 2];
for (int i = 0; i < b.length; i++) {
int index = i * 2;
int v = Integer.parseInt(s.substring(index, index + 2), 16);
b[i] = (byte) v;
}
return b;
}
サンプルIVバイト配列:
Androidの対iOSの:
43、34、95、101、57、150、75、100、250、178、194、70、253、236、92、70
43、34、95、101、57、-106、75、100、-6、-78、-62、70、-3、-20、92、70
デフォルトでは、Javaは符号付きの値としてバイトを表示しますので、あなたは、2つのプリントアレイ間の違いに気づくかもしれません。しかし、現実には、これらは実際には同じです。それはより多くの私はあなたが提供した例のIV配列の最後の5つの値を持つ小さなテーブルを追加します明確に。
|----------------------------------------|
| hex | 46 | FD | EC | 5C | 46 |
|----------------------------------------|
| unsigned | 70 | 253 | 236 | 92 | 70 |
|----------------------------------------|
| signed | 70 | -3 | -20 | 92 | 70 |
|----------------------------------------|
彼らは実際にそれらが異なる値として解釈されるように(ビット単位の)同じだけdiffentlyプリント。必要に応じて作成してください物事は正しい、私はプログラミングモードでの電卓といくつかの数字を見てお勧めします。通常、あなたは(も値のビット表現があるはずです)同じ16進値の符号なしの解釈対署名で遊ぶことができますので、バイト/ワード長を設定する方法があります。
代替Iとして発見小さなウェブサイトにもトリックを行いますunsigned型ビット/ HEXコンバータ、対署名含有しました。(そうでない場合は符号付きの値が不正確になり、あなたはどちらかのchar型を選択してください)
だから、IV-バイトコードの一部に何か問題があってはなりません。あなたは、パラメータとしてのみバイト配列を使用して文字列を作成するときが1があるかもしれません。EI:
byte[] decryptedData = decrypt(encryptedData, aesDeviceKey.getBytes(), aesIV.getBytes());
System.out.println("ble_ Cipher Decrypt:" + new String(decryptedData));
最も可能性の高い使用文字セットはUTF-8ではありませんので。(あなたが呼び出すことによってこれを決定することができCharset#defaultCharset
、その値を確認してください)。代替は次のようになります。
new String(decryptedData, StandardCharsets.UTF_8)
または:
new String(decryptedData, "UTF-8");