CryptLib decryption returns wrong value - swift

I am using Cross-Platform-AES for my AES encryption/decryption within my swift app. My encryption is working fine. But when I try to decrypt the service returns value it doesn't give me the correct result. Here how I am doing decryption.
public func decryptStrings(text:String)->String{
let hashKey=cryptoLib.sha256(key, length: 31)
let decryptedData = cryptoLib.decrypt(text.data(using: String.Encoding.utf8), key: hashKey, iv: iv)
let decryptedString=decryptedData?.base64EncodedString()
print("decryptedString \(decryptedString! as String)")
return decryptedString!
}
Please explain me how can I decrypt this in correct way.
Thanks
ENCRYPTION
public func base64Convertion (secretcode:String)->String
{
let hashKey=cryptoLib.sha256(key, length: 31)
let encryptedData=cryptoLib.encrypt(secretcode.data(using: String.Encoding.utf8), key: hashKey, iv: iv)
let encryptedString=encryptedData?.base64EncodedString()
print("encryptedString \(encryptedString! as String)")
return encryptedString!
}

I solved the problem by changing the Decryption method in this way
public func decryptStrings(text:String)->String{
let hashKey=cryptoLib.sha256(key, length: 31)
let decodedData = Data(base64Encoded: text, options: Data.Base64DecodingOptions())
let decryptedData = cryptoLib.decrypt(decodedData, key: hashKey, iv: iv)
let decryptedString=String(data: decryptedData!,encoding:String.Encoding.utf8)
print("decryptedString \(decryptedString!)")
return decryptedString!
}

Related

How to decrypt an encrypted data came from server with AES decryption?

I'm working on a project that'll open PDF books inside application. I'm fetching the books from the server and they're coming as locked pdf pages and I'm also fetching each pages' password with another API.
The problem is, the list of passwords are coming as AES encrypted. I can not decrypt them properly. I don't know what am I missing. My code is below. Waiting for your answers. Thank you :) (I'm using CrytoSwift library)
(I'm taking key and iv with an another function and keeping them in two different variables.)
import CryptoSwift
var myEncryptedData : String = ""
var key32 : String = ""
var iv16: String = ""
func decryptData() {
do {
let aes = try AES(key: Array(key32.utf8), blockMode: CBC(iv: Array(iv16.utf8)), padding: .pkcs7)
let ciphertext = try aes.decrypt(myEncryptedData.bytes)
print(String(data: Data(ciphertext), encoding: .utf8));
} catch {
print(error)
}
}
I tried to decrypt encryptedString with AES decryption by using CryptoSwift library but I couldn't fetch the data that I expected.
I just added this code just below "do" and it worked
let d = Data(base64Encoded: encryptedString)
Working version is:
do {
let d = Data(base64Encoded: encryptedString)
let aes = try AES(key: Array(key32.utf8), blockMode: CBC(iv: Array(iv16.utf8)), padding: .pkcs7)
let ciphertext = try aes.decrypt(d!.bytes)
let stringCipherText = String(data: Data(ciphertext), encoding: .utf8)
} catch {
print(error)
}

P384 Public Key getting "IncorrectParameterSize"

I am working on the ECDSA Algorithm where i am taking signature from the APIs and i have one local public key inside constant file.
Below is my code when i am trying to run this and verify the signature then i am getting error in this link
let publicKey = try P384.Signing.PublicKey.init(derRepresentation: privateKeyPemBytes)
I am receiving "incorrectParameterSize" this error from the catch block. Can anyone having idea about this Encryption algorithm and help me out?
func verifySignature(signedData: Data, signature: Data, publicKey: String) -> Bool {
var result = false
do {
if #available(iOS 14.0, *) {
let decodedData = Data(base64Encoded: publicKey)
let publicKeyPemBytes = [UInt8](decodedData!)
let publicKey = try P384.Signing.PublicKey.init(derRepresentation: privateKeyPemBytes)
let hash = SHA256.hash(data: signedData)
let signing384 = try P384.Signing.ECDSASignature(derRepresentation: signature)
if publicKey.isValidSignature(signing384, for: hash) {
result = true
}
} else {
// Fallback on earlier versions
}
} catch {
print("\(error)")
}
return result
}
In the discussion it turned out that the public key has the X.509/SPKI format, is ASN.1/DER encoded and is available as Base64 encoded string.
However, it is a P-256 key and not a P-384 key, which is the cause of the error. The fix is to use P256 in the code instead of P384.
The signature is in ASN.1/DER format, as Base64 encoded string.
Swift supports both the ASN.1/DER signature format and the P1363 signature format for ECDSA signatures (s. here for the difference).
The following code shows the verification for both signature formats using sample data:
import Foundation
import Crypto
// message to be signed
let msg = "The quick brown fox jumps over the lazy dog".data(using: .utf8)!
let hash = SHA256.hash(data: msg)
// public key import
let publicKeyX509DerB64 = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEMpHT+HNKM7zjhx0jZDHyzQlkbLV0xk0H/TFo6gfT23ish58blPNhYrFI51Q/czvkAwCtLZz/6s1n/M8aA9L1Vg=="
let publicKeyX509Der = Data(base64Encoded: publicKeyX509DerB64)
let publicKey = try! P256.Signing.PublicKey.init(derRepresentation: publicKeyX509Der!)
// verifying an ASN.1/DER encoded signature
let signatureDerB64 = "MEYCIQCDMThF51R3S3CfvtVQomSO+kotOMH6HfvVcx04a21QwQIhAP2Patj0N3CVoeB6yiZt/gEVh9qQ7mtyvF4FiWBYtE0a"
let signatureDer = Data(base64Encoded: signatureDerB64)
let signature1 = try! P256.Signing.ECDSASignature(derRepresentation: signatureDer!)
print(publicKey.isValidSignature(signature1, for: hash)) // true
// verifying a P1363 encoded signature
let signatureP1363B64 = "gzE4RedUd0twn77VUKJkjvpKLTjB+h371XMdOGttUMH9j2rY9DdwlaHgesombf4BFYfakO5rcrxeBYlgWLRNGg=="
let signatureP1363 = Data(base64Encoded: signatureP1363B64)
let signature2 = try! P256.Signing.ECDSASignature(rawRepresentation: signatureP1363!)
print(publicKey.isValidSignature(signature2, for: hash)) // true

How to solve "dataPaddingRequired" error CryptoSwift

I have key = "somesomesomesome".md5(), length is 32 bytes, iv is empty, trying to decrypt encrypted string using CryptoSwift:
let aes = try AES(key: key.bytes, blockMode: CBC(iv: []), padding: .noPadding)
let result = try aes.decrypt(encrypted)
let decrypted = String(bytes: result, encoding: .utf8)
getting error "dataPaddingRequired". What I am doing wrong?
Add this before setting up your AES:
let padding = Padding.noPadding.add(to: encrypted, blockSize: AES.blockSize)

Using CryptoSwift framework AES encryption with ECB and pkcs7 IN SWIFT4

IN swift I am trying to encrypt text same as CryptoJS encryption. But both are not same here I share with you URL, I need to do the same encryption in Swift. Please help me, here I attach my code also.
Demo CryptoJS encryption
in this URL we are using CryptoJS encryption with ECB and pkcs7. Same code I am doing in ios but not the same
import UIKit
import Foundation
import CryptoSwift
class CryptoViewController: UIViewController {
let KEY = "0123456789123456"
override func viewDidLoad() {
super.viewDidLoad()
self.aesCBC_Encrypt(AES_KEY: KEY, payload: "Hello World!")
}
func aesCBC_Encrypt(AES_KEY: String,payload: String) -> String {
var result = ""
do {
let key: [UInt8] = Array(AES_KEY.utf8) as [UInt8]
let iv = AES.randomIV(AES.blockSize)
let bytes = payload.bytes
let aes = try! AES(key: key, blockMode: ECB(), padding: .pkcs7)
//let encrypted = try aes.encrypt(Array(self.utf8))
let encrypted = try aes.encrypt(bytes)
print("encrypted: \(encrypted)")
result = encrypted.toHexString()
print("AES Encryption Result: \(result)")
} catch {
print("Error: \(error)")
}
return result
}
}
From my code, I am getting this Result
AES Encryption Result: 1b8019c2add38f33de9099aefd5369f5
But when I am try to Encryption from CryptoJS, Then I am getting this Result
Encrypted Text:
Aeoo7GP6b4l/Pdxz2RS+qA==

How do I encode an unmanaged<SecKey> to base64 to send to another server?

I'm trying to use key pair encryption to validate identity between my app and my PHP server. To do this I need to send the public key over to the server after I generate it in my app.
if let pubKey = NSData(base64EncodedData: publicKey, options: NSDataBase64DecodingOptions.allZeros)! {
println(pubKey)
}
publicKey is of type Unmanaged<SecKey>.
The error I'm getting in the above code is: Extra argument 'base64EncodedData' in call
How would I do this? Is there a better way?
Edit: This is how the keypair is generated:
var publicKeyPtr, privateKeyPtr: Unmanaged<SecKey>?
let parameters = [
String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
String(kSecAttrKeySizeInBits): 2048
]
let result = SecKeyGeneratePair(parameters, &publicKeyPtr, &privateKeyPtr)
let publicKey = publicKeyPtr!.takeRetainedValue()
let privateKey = privateKeyPtr!.takeRetainedValue()
let blockSize = SecKeyGetBlockSize(publicKey)
Edit 2: So the issue is that SecKey is not NSData, so my question here should be: How do I convert a publicKey:SecKey to NSData?
It seems that you can temporary store the key to keychain and then get it back and convert it to data:
func convertSecKeyToBase64(inputKey: SecKey) ->String? {
// First Temp add to keychain
let tempTag = "de.a-bundle-id.temp"
let addParameters :[String:AnyObject] = [
String(kSecClass): kSecClassKey,
String(kSecAttrApplicationTag): tempTag,
String(kSecAttrKeyType): kSecAttrKeyTypeRSA,
String(kSecValueRef): inputKey,
String(kSecReturnData):kCFBooleanTrue
]
var keyPtr: Unmanaged<AnyObject>?
let result = SecItemAdd(addParameters, &keyPtr)
switch result {
case noErr:
let data = keyPtr!.takeRetainedValue() as! NSData
// Remove from Keychain again:
SecItemDelete(addParameters)
let encodingParameter = NSDataBase64EncodingOptions(rawValue: 0)
return data.base64EncodedStringWithOptions(encodingParameter)
case errSecDuplicateItem:
println("Duplicate Item")
SecItemDelete(addParameters)
return nil
case errSecItemNotFound:
println("Not found!")
return nil
default:
println("Error: \(result)")
return nil
}
}
While the fact is barely documented, you can pull out everything you need (that is, modulus and exponent) from the SecKey using SecKeyCopyAttributes.
See here for the details.
Swift 4 method to get base64 string from SecKey, publicKey :)
guard let publicKeyData = SecKeyCopyExternalRepresentation(publicKey!, nil) else {
NSLog("\tError obtaining export of public key.")
return ""
}
let publicKeyNSData = NSData(data: publicKeyData as Data)
let publicKeyBase64Str = publicKeyNSData.base64EncodedString()