This question is similar to another question . Posting an answer here, with some changes!
I used the OpenSSL module available in Ruby and Plist gem.
Consider the password restriction profile.
passcode_payload ={ 'PayloadUUID' => 'RANDOM_STRING_UUID', 'PayloadOrganization' => 'PayloadOrganization', 'PayloadVersion' => 1, 'PayloadIdentifier' => 'com.test.PayloadIdentifier', 'PayloadType' => 'Configuration', 'PayloadDisplayName' => 'PayloadDisplayName', 'PayloadRemovalDisallowed' => false } passcode_payload_content = { 'PayloadDescription' => 'PayloadDescription', 'PayloadDisplayName' => 'PayloadDisplayName', 'PayloadIdentifier' => 'PayloadIdentifier', 'PayloadOrganization' => 'PayloadOrganization', 'PayloadType' => 'com.apple.mobiledevice.passwordpolicy', 'PayloadUUID' => "RANDOM_STRING_UUID", 'PayloadVersion' => 1, 'allowSimple' => true, 'forcePIN' => true 'maxPINAgeInDays' => 20, 'minComplexChars' => 1, 'minLength' => 4, 'requireAlphanumeric' => true }
Usually for a normal profile, passcode_payload_content
goes into passcode_payload['PayloadContent']
as an array of dictionaries.
passcode_payload ['PayloadContent'] = [passcode_payload_content]
But for the encrypted profile, PayloadContent
should be deleted and EncryptedPayloadContent
should be used in accordance with the configuration profile key reference document .
Question 1: What data from the .mobileconfig profile is actually encrypted, which are included in the section (data) .. (/ data) of the key (key) EncryptedPayloadContent (/ key)
from the document
To encrypt a profile, follow these steps:
Remove the PayloadContent
array and serialize it as the correct plist. Note that the top-level object in this plist is an array, not a dictionary. CMS encryption of serialized plist as data envelopes. Serialize encrypted data in DER format. Set serialized data as a value as a data item in a profile using the EncryptedPayloadContent
key
Since the top level object in plist should be an array
passcode_payload_content_array = [passcode_payload_content]
Serialization for the correct plist
to_be_encrypted_plist = passcode_payload_content_array.to_plist
Encrypting the contents of the certificate payload,
device_certificate = OpenSSL::X509::Certificate.new File.read('deviceIdentityCertificate.pem') encrypted_payload = OpenSSL::PKCS7.encrypt([device_certificate],to_be_encrypted_plist, OpenSSL::Cipher::Cipher::new("des-ede3-cbc"),OpenSSL::PKCS7::BINARY)
Question 2: Is the data in binary format (.der) or base64 encoded?
Add encrypted payload content to the original payload in the format
passcode_payload['EncryptedPayloadContent'] = StringIO.new(encrypted_payload.to_der)