logo

Insecure encryption algorithm - SHA1 - Swift


Need

Upgrade to a secure encryption algorithm


Context

  1. Usage of Swift for iOS and macOS app development
  2. Usage of CommonCrypto for cryptographic operations

Description

Insecure Code Example

import CommonCrypto

func sha1Hash(_ string: String) -> String {
    let data = string.data(using: .utf8)!
    var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH))
    data.withUnsafeBytes {
        _ = CC_SHA1($0.baseAddress, CC_LONG(data.count), &digest)
    }
    let hexBytes = digest.map { String(format: "%02hhx", $0) }
    return hexBytes.joined()
}

let password = "password123"
let hashedPassword = sha1Hash(password)
print("SHA1 Hashed Password: \\(hashedPassword)")

The code above is a Swift function that hashes a string using SHA1, an insecure encryption algorithm. SHA1 (Secure Hash Algorithm 1) is a cryptographic hash function that takes an input (or 'message') and returns a fixed-size (160-bit) hash value. In the code, the `sha1Hash` function takes a string as input and converts it to a byte array (`data`). This byte array is then hashed using the `CC_SHA1` function from the `CommonCrypto` library, which is included in the iOS SDK. The resulting hash is a byte array (`digest`) which is then converted to a hexadecimal string (`hexBytes`) and returned. The problem with this code is that SHA1 is considered insecure. It has been proven that SHA1 is vulnerable to collision attacks, which means that two different inputs can produce the same hash. In the context of password storage, an attacker can take advantage of this vulnerability to guess the password. For instance, the `password` variable in the code is a clear text password that is being hashed using the insecure `sha1Hash` function. An attacker who gains access to these hashed passwords could potentially reverse-engineer them, despite the hashing, due to the known vulnerabilities in SHA1.

Steps

  1. Replace the usage of SHA1 algorithm with a more secure hashing algorithm, such as SHA256 or bcrypt.
  2. Update the code to use a secure cryptographic library or framework that provides secure hashing functions.
  3. Ensure that the chosen hashing algorithm is resistant to pre-image attacks and has a sufficiently long output length.
  4. Consider using a salt value when hashing passwords to further enhance security.
  5. Regularly update the cryptographic libraries and frameworks used in the application to ensure they are up-to-date with the latest security patches.

Secure Code Example

import CommonCrypto

func sha256Hash(_ string: String) -> String {
    let data = string.data(using: .utf8)!
    var digest = [UInt8](repeating: 0, count:Int(CC_SHA256_DIGEST_LENGTH))
    data.withUnsafeBytes {
        _ = CC_SHA256($0.baseAddress, CC_LONG(data.count), &digest)
    }
    let hexBytes = digest.map { String(format: "%02hhx", $0) }
    return hexBytes.joined()
}

let password = "password123"
let hashedPassword = sha256Hash(password)
print("SHA256 Hashed Password: \\(hashedPassword)")

The above code is a revised version of the original code that was using the insecure SHA1 hashing algorithm. The new code now uses the more secure SHA256 hashing algorithm. The function `sha256Hash(_:)` takes a string as input and returns its SHA256 hash. The string is first converted to data using UTF-8 encoding. Then, a digest array of `UInt8` is created with a count equal to `CC_SHA256_DIGEST_LENGTH`. The `withUnsafeBytes` method is used to perform a closure while ensuring the data remains valid. Inside the closure, the `CC_SHA256` function is called to perform the hashing operation. The base address of the data and the count of the data are passed as arguments, along with the digest array. After the hashing operation, the digest array is converted to hexadecimal strings and joined together to form the final hashed string. The password is then hashed using the `sha256Hash(_:)` function and printed. This code is more secure than the original code as it uses a stronger hashing algorithm. However, it is recommended to use a salt value when hashing passwords to further enhance security. Also, it is important to regularly update the cryptographic libraries and frameworks used in the application to ensure they are up-to-date with the latest security patches.


References

  • 262 - Insecure encryption algorithm - SHA1

  • Last updated

    2023/09/18