Skip to content

Sign a profile

Provide a complete nested signing object to receive signed DER:

const result = await generateProfile({
profile,
signing: {
identity: {
type: "pkcs12",
data: { encoding: "base64", value: secrets.pkcs12Base64 },
passphrase: secrets.pkcs12Passphrase,
},
certificateChain: secrets.chainPem.map((value) => ({
encoding: "pem" as const,
value,
})),
digestAlgorithm: "sha256",
},
});

Uint8Array, strict base64, and PEM certificate inputs are supported. The PKCS#12 container must have exactly one unambiguous RSA private-key/certificate match, and the signing key must be at least 2048 bits. Certificates already present in the container and supplied chain are deduplicated by SHA-256 fingerprint.

PKCS#12 certificate safe contents and private-key bags may be plaintext or password encrypted. The allow-list accepts PKCS#12 SHA-1/3DES PBE, legacy SHA-1/RC2-40 or SHA-1/RC2-128 PBE, and PBES2 with PBKDF2 using HMAC-SHA-1, SHA-256, SHA-384, or SHA-512 plus AES-128-CBC, AES-192-CBC, or AES-256-CBC. Unknown algorithms and malformed parameters fail closed.

RC2 decryption preserves compatibility with existing exports, including macOS LibreSSL’s RC2-40 certificate safe contents. Prefer PBES2/AES when creating new containers: RC2-40 offers only 40 effective key bits. The library verifies the container MAC before decryption and keeps its own bounded, internal RC2 decoder; it never enables a global OpenSSL legacy provider. This input compatibility does not change RSA/SHA-256 profile signing or add profile encryption.

The RC2 algorithm and compatibility OIDs follow RFC 2268 and RFC 7292, Appendix C (accessed 2026-10-29).

The beta output is attached CMS/PKCS#7 SignedData with content-type, message-digest, and signing-time authenticated attributes. The chain is embedded in the output; the package never downloads or invents it.

If signing exists but the identity, key, certificate, passphrase, algorithm, or key/certificate match is invalid, the call returns an error. It never emits unsigned XML as a fallback.

An expired signer certificate is an error. A not-yet-valid certificate and a certificate expiring within 30 days produce warnings. Whether Apple devices trust/install a particular developer certificate remains deployment policy and must be tested on target platform versions.

The package never reads environment variables. Applications migrating to the package may standardize on:

UDID_TOOLS_SIGNING_PKCS12_BASE64
UDID_TOOLS_SIGNING_PKCS12_PASSPHRASE
UDID_TOOLS_SIGNING_CERTIFICATE_CHAIN_PEM

Read them through your validated configuration/secret manager and pass the values explicitly. Avoid multiline-chain ambiguity by parsing each PEM block into a separate array item.