14

On iOS, the Certificate, Key, and Trust Services API contains the following padding types:

  • kSecPaddingNone
  • kSecPaddingPKCS1
  • kSecPaddingPKCS1MD2
  • kSecPaddingPKCS1MD5
  • kSecPaddingPKCS1SHA1

A user on the Apple CDSA mailing list says that "kSecPaddingPKCS1 [...] is the same as PKCS #1 1.5". The Certificate, Key, and Trust Services Reference annotates the latter three padding types (kSecPaddingPKCS1MD2, kSecPaddingPKCS1MD5, and kSecPaddingPKCS1SAH) with "Standard ASN.1 padding will be done, as well as PKCS1 padding of the underlying RSA operation".

  1. What is the difference to kSecPaddingPKCS1?
  2. Is kSecPaddingPKCS1 just the raw padding of the underlying RSA operation according to RFC 3447?
  3. When signing a SHA-256, SHA-384, or SHA-512 digest with SecKeyRawSign(), does a developer need to use kSecPaddingPKCS1 and perform the ASN.1 padding herself? Is the ASN.1 padding necessary or can it be omitted?

Any hint that points me in the right direction is highly appreciated.

Manuel Binna
  • 1,225
  • 2
  • 14
  • 23

1 Answers1

21

PKCS#1 contains two "paddings" for signatures with RSA, the "new" one (called PSS, added in version 2.1) and the "old" one (renamed "v1.5" since it was already in version 1.5 of PKCS#1). We are talking about the v1.5 padding.

When some data is signed, it is first hashed with a suitable hash function (e.g. SHA-1), then the hash value (20 bytes if using SHA-1) is wrapped into two successive layers:

  1. The hash value is encoded into an ASN.1-based structure which also specifies which hash function was used. In practice, if the hash value is H, then the first wrapping results in the sequence of bytes A || H where "||" is concatenation, and "A" is a header which is specific to the hash function (typically 15 to 20 bytes).

  2. The "A || H" is expanded with some extra bytes:

0x00 0x01 0xFF 0xFF ... 0xFF 0x00 || A || H

The number of bytes of value 0xFF is adjusted to that the total size equals the size of the RSA modulus (i.e. 128 bytes for a 1024-bit RSA key).

The second step is what PKCS#1 calls "type 1 padding".

kSecPaddingPKCS1 means that the function performs only the second step: it assumes that the input data is already the proper "A || H". Note that SSL/TLS (up to version 1.1) uses a signature variant which requires this mode (there's no "A", but there are two hash functions). With kSecPaddingPKCS1SHA1, the signature function expects the hash value as input, and adds the "A" header itself.

For a proper, standards-compliant signature which can be verified by third-party implementations, the "A" header must be added at some point. You can add it yourself and use kSecPaddingPKCS1, or use kSecpaddingPKCS1SHA1 and let the engine add it itself, which is probably less error-prone.

(As of 2011, use of SHA-1 is not recommended; you'd better switch to SHA-256 or SHA-512. Also, the API you are trying to use seem to be quite low-level, and the whole thing suspiciously looks as if you are tying to implement your own cryptographic protocol instead of using an existing library or framework.)

Community
  • 1
  • 1
Thomas Pornin
  • 72,986
  • 14
  • 147
  • 189
  • 1
    Thank you for that great answer! I am aware that this is quite low-level. I am writing my diploma thesis about iOS application security and need to dig a little deeper into the security APIs. I don't implement my own cryptographic protocol. To recap, in order to use e.g. SHA-512 I would calculate the digest H and concatenate that with the header from [PKCS#1](ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1.pdf): `SHA-512: (0x)30 51 30 0d 06 09 60 86 48 01 65 03 04 02 03 05 00 04 40 || H`. The result together with `kSecPaddingPKCS1` is the input for `SecKeyRawSign()`. Is that correct? – Manuel Binna Feb 22 '11 at 12:28
  • Cool, then my question is fully answered. – Manuel Binna Feb 22 '11 at 14:33
  • "As of 2011, use of SHA-1 is not recommended" Could you link an article to support/explain this? – lhunath Mar 04 '12 at 14:08
  • 1
    @lhunath: see for instance [NIST special publication 800-107](http://csrc.nist.gov/publications/nistpubs/800-107/NIST-SP-800-107.pdf), in particular the bit about: "SHA-1 should not be used in any new digital signature applications that require at least 80 bits of security. Furthermore, SHA-1 shall not be used in any digital signature applications after the end of 2010". There are (yet theoretical) weaknesses in SHA-1 with regards to collision resistance, so its use is officially discouraged in new application (for interoperability with legacy apps, it is still "Approved", in NIST parlance). – Thomas Pornin Mar 04 '12 at 22:35
  • how i can use SecPadding.PKCS8 since the IOS not support that ??!! – Abdulrahman Masoud Nov 28 '16 at 09:58