<!--
{
  "documentType" : "article",
  "framework" : "Security",
  "identifier" : "/documentation/Security/signing-and-verifying",
  "metadataVersion" : "0.1.0",
  "role" : "article",
  "title" : "Signing and Verifying"
}
-->

# Signing and Verifying

Create and evaluate digital signatures to establish the validity of code or data.

## Discussion

You create a cryptographic signature on a block of data by first creating a hash of the data and then encrypting this digest with your private key. A recipient uses your public key to decrypt the signature, while independently re-creating the hash of the original data. If the decrypted hash and the computed one match, the recipient can be sure the data is from the owner of the private key that corresponds to the public key.

Often, you sign a block of data as a side effect of performing some other operation. For example, as a final step in distributing your app, Xcode signs the code on your behalf using one of your cryptographic identities (see [Code Signing Guide](https://developer.apple.com/library/archive/documentation/Security/Conceptual/CodeSigningGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40005929)). When you want to sign or verify a block of data in your app, you use functions provided by the certificate, key, and trust services API.

### Get Your Private Key

Begin by getting your private key, as described in [Getting an Existing Key](/documentation/Security/getting-an-existing-key), either from the keychain or from an identity (which itself probably resides in the keychain). Then, select one of the signing algorithms. For example:

```swift
let privateKey: SecKey = <# a key #>
let algorithm: SecKeyAlgorithm = .rsaSignatureMessagePKCS1v15SHA512
```

This algorithm indicates that the signing function should first create an SHA-512 digest of the input data and then use RSA encryption with PKCS#1 padding. But you can choose different options, along a number of dimensions:

- **Digest vs. message.** If you already have a digest of the data, you can use one of the `Digest` algorithms. For example, the above algorithm might become [`rsaSignatureDigestPKCS1v15SHA512`](/documentation/Security/SecKeyAlgorithm/rsaSignatureDigestPKCS1v15SHA512). If you do this, be sure that the actual hashing matches the named hashing algorithm.
- **Digital signature algorithm type.** If you have elliptic curve keys instead of RSA, you can use an Elliptic Curve Digital Signature Algorithm (ECDSA). For example, the above algorithm might become [`ecdsaSignatureMessageX962SHA512`](/documentation/Security/SecKeyAlgorithm/ecdsaSignatureMessageX962SHA512).

With a key and an algorithm selected, you can test the compatibility of these with the signing operation using the [`SecKeyIsAlgorithmSupported(_:_:_:)`](/documentation/Security/SecKeyIsAlgorithmSupported(_:_:_:)) function:

```swift
guard SecKeyIsAlgorithmSupported(privateKey, .sign, algorithm) else {
    throw <# an error #>
}
```

This function might return <doc://com.apple.documentation/documentation/Swift/false>, for example, if the key’s [`kSecAttrCanSign`](/documentation/Security/kSecAttrCanSign) attribute is set to <doc://com.apple.documentation/documentation/Swift/false>. This situation might happen if you used a public key instead of a private one (despite the variable name). Similarly, if you attempt to use an RSA key with one of the ECDSA algorithms, the check fails.

Finally, you can create the signature with a call to the [`SecKeyCreateSignature(_:_:_:_:)`](/documentation/Security/SecKeyCreateSignature(_:_:_:_:)) function:

```swift
var error: Unmanaged<CFError>?
guard let signature = SecKeyCreateSignature(privateKey,
                                            algorithm,
                                            data as CFData,
                                            &error) as Data? else {
                                                throw error!.takeRetainedValue() as Error
}
```

If something goes wrong, the function returns a `nil` signature and populates the error reference with a <doc://com.apple.documentation/documentation/CoreFoundation/CFError> object that explains the failure. In Objective-C, you transfer management of the error object, if it exists, to Automatic Reference Counting (ARC). In Swift, you transfer control of this unmanaged object’s memory to the system with a call to <doc://com.apple.documentation/documentation/Swift/Unmanaged/takeRetainedValue()> and recast as an <doc://com.apple.documentation/documentation/Swift/Error>.

### Transmit the Data

After you successfully generate a signature, you transmit the data and signature to any interested party. Using your public key, the recipient then verifies the signature by performing a set of operations that resemble the signing process. As the receiver, you first retrieve the public key, possibly from a certificate, as described in [Getting an Existing Key](/documentation/Security/getting-an-existing-key). Then, using the same algorithm as was used for signing, you test that the key and algorithm are mutually compatible with the verification operation:

```swift
guard SecKeyIsAlgorithmSupported(publicKey, .verify, algorithm) else {
    throw <# an error #>
}
```

The [`SecKeyIsAlgorithmSupported(_:_:_:)`](/documentation/Security/SecKeyIsAlgorithmSupported(_:_:_:)) function returns <doc://com.apple.documentation/documentation/Swift/false> if you use the wrong kind of key for the operation or algorithm. You then conduct the verification with a call to the [`SecKeyVerifySignature(_:_:_:_:_:)`](/documentation/Security/SecKeyVerifySignature(_:_:_:_:_:)) function:

```swift
var error: Unmanaged<CFError>?
guard SecKeyVerifySignature(publicKey,
                            algorithm,
                            data as CFData,
                            signature as CFData,
                            &error) else {
                                throw error!.takeRetainedValue() as Error
}
```

If the call succeeds and the signature and data are intact, the return value is <doc://com.apple.documentation/documentation/Swift/true>. If the function returns <doc://com.apple.documentation/documentation/Swift/false>, either the data or signature has been altered, the public key doesn’t match the private key, or some other error has occurred. Handle the error and transfer error object ownership to the system as needed.

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)