I'm trying to convert a block of Java code to Swift but I'm not getting
This is the block that I want to convert:
https://github.com/K4CZP3R/tapo-p100-java-poc/blob/main/src/main/java/KspEncryption.java
public static C658a decodeTapoKey(String key, KspKeyPair keyPair) {
KspDebug.out("Will try to decode the following key: " + key);
try {
byte[] decode = KspB64.decode(key.getBytes("UTF-8"));
byte[] decode2 = KspB64.decode(keyPair.getPrivateKey());
Cipher instance = Cipher.getInstance("RSA/ECB/PKCS1Padding");
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey p = kf.generatePrivate(new PKCS8EncodedKeySpec(decode2));
instance.init(Cipher.DECRYPT_MODE, p);
byte[] doFinal = instance.doFinal(decode);
byte[] bArr = new byte[16];
byte[] bArr2 = new byte[16];
System.arraycopy(doFinal, 0, bArr, 0, 16);
System.arraycopy(doFinal, 16, bArr2, 0, 16);
return new C658a(bArr, bArr2);
}
catch (Exception ex)
{
KspDebug.out("Something went wrong: " + ex.getMessage());
return null;
}
}
Here is the same code but this time in Python: https://github.com/K4CZP3R/tapo-p100-python/blob/21e4bf9b61c08a3eb215293198968f82cd80ab2d/encryption.py
def decode_handshake_key(key: str, key_pair: KeyPair) -> TpLinkCipher:
logger.debug(f"Will decode handshake key (...{key[5:]}) using current key pair")
decode: bytes = base64.b64decode(key.encode("UTF-8"))
decode2: bytes = base64.b64decode(key_pair.get_private_key())
cipher = PKCS1_v1_5.new(RSA.import_key(decode2))
do_final = cipher.decrypt(decode, None)
if do_final is None:
raise ValueError("Decryption failed!")
b_arr:bytearray = bytearray()
b_arr2:bytearray = bytearray()
for i in range(0, 16):
b_arr.insert(i, do_final[i])
for i in range(0, 16):
b_arr2.insert(i, do_final[i + 16])
And this is what I have right now in Swift that is not correct
func decodeTapoKey(key: String, keyPair: KspKeyPair) {
let data = key.data(using: .utf8)!
let b64 = data.base64EncodedString(options: .lineLength76Characters)
let data2 = keyPair.privateKey.data(using: .utf8)!
let b642 = data2.base64EncodedString(options: .lineLength76Characters)
do {
let privateKey = try PrivateKey(pemNamed: keyPair.getPrivateKey())
let encrypted = try EncryptedMessage(base64Encoded: key)
let clear = try encrypted.decrypted(with: privateKey, padding: .PKCS1)
// Then you can use:
let data = clear.data
let base64String = clear.base64String
let string = try clear.string(encoding: .utf8)
} catch {
print("error")
}
I was trying to use the Pod SwiftyRSA.
Can someone help me with this?
It looks as if there is the following scenario:
On client side we could:
The source code for this function could look like this:
Test
One can generate a private and public test key as well as an AES key with 256 bit (= 32 bytes). With this data we should get the same binary output for the key as in the Python script.
For the output of hex data we can use the function
hexDescriptionfrom this fine answer: https://stackoverflow.com/a/39075044.A completely self-contained example:
Decrypt.swift
ViewController.swift
The output is:
Python
Based on your Python script also a completely self-contained example:
And the output of this Python program is exactly the same as that of the iOS Swift program. So the Swift part seems to work correctly.
Java
Also for the Java routine the same output should be given. Let's test it with this self-contained Java example:
And indeed the Java program delivers the same result.