Home > Mac administration, macOS, Management Profiles, Mobile Device Management > Creating macOS configuration profiles with encrypted payloads

Creating macOS configuration profiles with encrypted payloads

Recently, I was asked to create a configuration profile with an encrypted payload. This is a payload where the settings installed by the profile are not readable when you look at the .mobileconfig file. Instead, the payload with the settings is encrypted and are only readable once the payload contents are decrypted using the private key of a certificate which is also installed on the Mac in question.

In researching how to do this, I found that Apple’s documentation on encrypted payloads is very sparse and largely consists of the following (from https://developer.apple.com/documentation/devicemanagement/using_configuration_profiles):

Screen Shot 2019 09 15 at 11 15 41 PM

Example commands for CMS encryption of the property list are not provided in Apple’s documentation, but it is possible to use /usr/libexec/mdmclient to encrypt profile payloads:

https://mosen.github.io/profiledocs/troubleshooting/mdmclient.html#encrypt

To see how this works, let’s go through the process of setting up a certificate which can be used for encrypting a profile followed by using that certificate to encrypt the profile. For more, please see below the jump.

Before we begin creating the certificate, I want to note that the certificate used in this example is going to be a self-signed root certificate. Using a self-signed root certificate is fine for prototyping and testing, but you should use a certificate issued by a trusted certificate authority if you’re using this method in production.

Creating the certificate

1. Run the following commands to generate a private key:

openssl genrsa -des3 -passout pass:x -out encryptprofiles.pass.key 2048
openssl rsa -passin pass:x -in encryptprofiles.pass.key -out encryptprofiles.key

Screen Shot 2019 09 15 at 1 55 35 PM

Screen Shot 2019 09 15 at 1 57 00 PM

Once the encryptprofiles.key file is generated, the encryptprofiles.pass.key file may be removed as it is no longer needed.

2. Run the following command to generate a certificate signing request (CSR):

openssl req -new -key encryptprofiles.key -out encryptprofiles.csr

Screen Shot 2019 09 15 at 1 58 58 PM

You will be asked a number of questions. The one which ultimately matters in this case is the Common Name question, as that is the one which is the name assigned to the certificate. In this case, I am setting encryptprofiles.company.com as the Common Name for the certificate.

Note: The challenge password can be left blank.

3. Once the CSR has been generated, run the following command to create a public key using the private key and CSR:

openssl x509 -req -sha256 -days 365 -in encryptprofiles.csr -signkey encryptprofiles.key -out encryptprofiles.crt

Screen Shot 2019 09 15 at 1 59 51 PM

4. Combine both the private key and public key into one text file named bothprivateandpublickeys.txt by running the following command:

cat encryptprofiles.key encryptprofiles.crt > bothprivateandpublickeys.txt

Screen Shot 2019 09 15 at 2 00 19 PM

5. Run the following command to generate a .p12 file which uses the contents of the bothprivateandpublickeys.txt file to generate a .p12 archive file which contains both the private and public key:

openssl pkcs12 -export -in bothprivateandpublickeys.txt -out bothprivateandpublickeys.p12

Screen Shot 2019 09 15 at 2 00 59 PM

You will be asked to set and verify an export password. You will need this password later, so make a note of it.

In this case, the following password is being used: password123

Creating a certificate profile

My next step was to create a configuration profile using ProfileCreator which included both the bothprivateandpublickeys.p12 file and the export password needed to unlock the .p12 file. This profile will import the .p12 file and use it to deploy the encryptprofiles.company.com certificate as a trusted root certificate.

Screen Shot 2019 09 15 at 5 37 23 PM

Screen Shot 2019 09 15 at 5 37 29 PM

Once built, the profile looks like this:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>Password</key>
<string>password123</string>
<key>PayloadContent</key>
<data>
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
Wm5/7Wrf5QICCAA=
</data>
<key>PayloadDescription</key>
<string>Adds a PKCS#12-formatted certificate</string>
<key>PayloadDisplayName</key>
<string>Certificate</string>
<key>PayloadIdentifier</key>
<string>com.company.profile.2F8AA603-60C4-4BFB-AB9B-CF08F9F517F0.com.apple.security.pkcs12.2FE69591-5B8E-4017-9753-5074813B3F8B</string>
<key>PayloadOrganization</key>
<string></string>
<key>PayloadType</key>
<string>com.apple.security.pkcs12</string>
<key>PayloadUUID</key>
<string>2FE69591-5B8E-4017-9753-5074813B3F8B</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</array>
<key>PayloadDescription</key>
<string>Self-signed root certificate for encrypting profiles</string>
<key>PayloadDisplayName</key>
<string>encryptprofiles.company.com certificate</string>
<key>PayloadIdentifier</key>
<string>com.company.profile.2F8AA603-60C4-4BFB-AB9B-CF08F9F517F0</string>
<key>PayloadOrganization</key>
<string>Company Name</string>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>2F8AA603-60C4-4BFB-AB9B-CF08F9F517F0</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

The final step is to install the profile, so that we can use it to encrypt another configuration profile’s payload. The profile installation can be performed via MDM, using the profiles command line tool or by double-clicking on the profile to install it.

In this case, I’m signing the certificate with my Developer ID Application signing certificate and then double-clicking to install it.

Screen Shot 2019 09 15 at 4 40 41 PM

Screen Shot 2019 09 15 at 2 47 03 PM

Encrypting a profile

Once the certificate profile is installed on a particular Mac, it should appear in the System keychain as a trusted root.

Screen Shot 2019 09 15 at 2 47 25 PM

Once the certificate is showing up in Keychain Access as trusted, it can be used to encrypt profiles. To do this, run a command similar to the one shown below:

/usr/libexec/mdmclient encrypt "certificate_common_name_goes_here" /path/to/profile_to_encrypt_goes_here.mobileconfig

In my case, I’m running the following command to encrypt a configuration profile named Company WiFi.mobileconfig:

Screen Shot 2019-09-15 at 2.08.11 PM

/usr/libexec/mdmclient encrypt "encryptprofiles.company.com" "/Users/username/Desktop/Company WiFi.mobileconfig"

A new profile should appear named Company WiFi.encrypted.mobileconfig.

Screen Shot 2019-09-15 at 2.07.50 PM

The original Company WiFi.mobileconfig profile looks like this, with the profile’s settings listed under PayloadContent:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>EncryptionType</key>
<string>WPA</string>
<key>Password</key>
<string>password123</string>
<key>PayloadDescription</key>
<string>Configures Wi-Fi settings</string>
<key>PayloadDisplayName</key>
<string>Wi-Fi</string>
<key>PayloadIdentifier</key>
<string>com.company.C9B2F74E-C5C7-45D9-A750-D68A97362932.com.apple.wifi.managed.6DDBBC7C-0382-4378-9552-ABA2EF797804</string>
<key>PayloadOrganization</key>
<string></string>
<key>PayloadType</key>
<string>com.apple.wifi.managed</string>
<key>PayloadUUID</key>
<string>6DDBBC7C-0382-4378-9552-ABA2EF797804</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>SSID_STR</key>
<string>Secure</string>
</dict>
</array>
<key>PayloadDescription</key>
<string>Connect to the company WiFi network</string>
<key>PayloadDisplayName</key>
<string>Company WiFi</string>
<key>PayloadIdentifier</key>
<string>com.company.C9B2F74E-C5C7-45D9-A750-D68A97362932</string>
<key>PayloadOrganization</key>
<string>Company Name</string>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>C9B2F74E-C5C7-45D9-A750-D68A97362932</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

The new Company WiFi.encrypted.mobileconfig profile looks like this, with the profile’s settings encrypted and listed under EncryptedPayloadContent:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"&gt;
<plist version="1.0">
<dict>
<key>EncryptedPayloadContent</key>
<data>
MIAGCSqGSIb3DQEHA6CAMIACAQAxggGFMIIBgQIBADBpMFwxCzAJBgNVBAYTAlVTMRAw
DgYDVQQHDAdBbnl0b3duMRUwEwYDVQQKDAxDb21wYW55IE5hbWUxJDAiBgNVBAMMG2Vu
Y3J5cHRwcm9maWxlcy5jb21wYW55LmNvbQIJALxDhukWhMCrMA0GCSqGSIb3DQEBAQUA
BIIBACxbNqqj3BcfuLogNjSsDruaZPfZ075CaZXQ61GRdV5zaXc8ISIEJerB8BSrUhbz
dH6xRoz8SI3DDF+YeHI4S0yE1ago1ca+o+o+0DnVn4H6QRISv1k95+St2ZR6kUvc7zY+
KOpSvdH6cgghN3D+y7kcmeCI3vjIVQLWDjAglcO8grj9Z/8hvHC83NIavKxEMIwXJZiJ
65wX2UunsHBxjikx4p99xdddYZrG44rWBW57oJdc6Z01+QFxes/ZO2kx231q+Qa/D7h4
NHa0CMxSPxcTsJFs/Ws1tGHTWbvmKYD6XW+H3nIZlHfx7Yw9p/Fnr3Th4Laq4hJ6hofE
de5Hlv8wgAYJKoZIhvcNAQcBMBQGCCqGSIb3DQMHBAhy5qm6p+3eLKCABIIDiJ5fheba
qXFZjeu3C+kEAlhmPKyGWA1Kehb1+RHN5HuueoMPG0jK6i8mM5qY10aP22vW7E56c1V0
S6Iqw4/x8wbsP+ssGFR/m9NEwg01XUIh8EtGVD2RULXtx4YZ49yMP2h/PhhEL3t3i0qK
KALqVXitulAc0EB4UTOjLIHVhmOzZwAfhWBbcyZ1HECnmJzADb+Fg3yl/WfPovjLPdxm
3oUYypnm5FLxxZphrKq+VUwapb5QtWN8PlHzyQkOzbzSyD2nz8q1gougIg4Gz4oid0tA
vwxzYzljIq5tpPDR/NXq9S/AImWm0hwlA0wcE/7jA4s8zirpDzJqsdxWbD5CFv4W3WkH
9M70rWLvm/ytsRu0Ip8xZ2k0EnbB9xWwvzYvAx1g+oB7WJQTaLkXafmiS3ttJhEC9dJx
eGPwokqG+XTg5xZOyIsfuiim7CHFetFChaRuDN/scgEsLAHxmWVYQa6Bxj1VQlIl5kpR
TRv+LTaK/uZWGVrUsVMcD+UuJ5vcuElYUfRt/Egvkem/pUfqHoITVicDG7E6zLCLClTe
cCifRj0Kds3qik3BfL1J3U27uZ//RFGZP65TN6OjKHtJJjWOGOjyvrZABNnbVyPPCDjL
x8Uj8/KOnRGTv4EwnMiI2j7w2iJwJ7G13kP6+Pq3jXGs+R2xfHFm8OhGUAAJRmXCvf3G
eYg+HZjIbQoIQoDFln1GV1nw4+qS6JLcDsQeZfv8Ww/RiZ3NtjlmRFU2eKfRvSS2GmYk
vy3/54xbDEqVsVxv0CedbLZcn5eKWU3eNvQTO1jhg/boz2x+Su3u4UUwQi04WBKRZQSd
bQ/esnzTfswWWKVht1kaWVNdBPinBPtoOxCn6eOGRPJ44x/P0qECV5XZSpVe6GwUVl5z
Ms5t81R4O8ehGxv7tOByEbF/dREaPFy50sQFMuUglAl1MH/eGvH54JhEo8rae/iGMqKN
3P5QkI6otZiAYf7wj4oTLY2IQkuS5v5alLAb80gEcyYdYEOzQaBty1WoO8mbV7U8fpn6
ag4JvJpG+S3gp9W51fr5P//frud1N5V12+hhGmoBMjqClFWbGFTaacMqs0OmNGMAdW+Z
A5d/bPCNKqk7zdJKqnygLjdJAoAHgAe2eciq2ECE/VDueluRlhE0HRihw8ngO53ewdRx
uUd1wXXsuzWh1emb5UlZ2kje4LOeESc6dPjXbXm2dPUECP6Xy/YXzBwXAAAAAAAAAAAA
AA==
</data>
<key>PayloadDescription</key>
<string>Connect to the company WiFi network</string>
<key>PayloadDisplayName</key>
<string>Company WiFi</string>
<key>PayloadIdentifier</key>
<string>com.company.C9B2F74E-C5C7-45D9-A750-D68A97362932</string>
<key>PayloadOrganization</key>
<string>Company Name</string>
<key>PayloadScope</key>
<string>System</string>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>C9B2F74E-C5C7-45D9-A750-D68A97362932</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

Installing an encrypted profile

Assuming the certificate profile is installed on a particular Mac, the encrypted profile can now be installed. The profile installation can be performed using the profiles command line tool or by double-clicking on the profile to install it.

If the certificate used to decrypt the profile is present and everything is working properly, the encrypted profile should install without a problem.

Screen Shot 2019 09 15 at 5 12 20 PM

If there is a problem with decrypting the profile, the process will error because the Mac won’t be able to read the profile’s encrypted payload.

Notes on this process

  • It is absolutely necessary for the certificate used to encrypt the profile to be deployed to the Mac receiving the encrypted profile and necessary for that certificate to include the private key.
  • It is also necessary for the export password used to protect the .p12 file be provided, either in the profile itself or manually provided when the certificate profile is installed.
    • The reason is that the private key is used to decrypt the profile’s encrypted content and the export password is used to make that possible.
  • The certificate must be deployed to the Mac receiving the encrypted profile before the encrypted profile is. If not, the encrypted profile won’t be readable by the Mac and the profile won’t install.

Screen Shot 2019 09 15 at 5 58 40 PM

  • You likely won’t be able to deploy the encrypted profile using an MDM server.
    • The reason is that when the profile was uploaded to the MDM server, the MDM server may try to read the profile and fail because it doesn’t have access the certificate used to decrypt the encrypted profile’s contents. This causes the upload process to halt and display an error. Instead, you will need to install the encrypted profile using the profiles command line tool.

 

  1. Fred Johnsen
    July 10, 2020 at 4:16 am

    This would no longer be possible if the install verb is removed from the profiles binary…

  2. David
    May 23, 2021 at 8:00 pm

    Thank you so much for your extensive description of this process…. I am complete not at ease at giving some third party mdm company the keys to the castle via the configuration of all our mobile devices. Using this is can have them distribute the content of the device configuration whilst they have no access to it themselves at the cost of having to manually install a decryption key on the devices prior to enrolment.

    This may seems to remove most of the benefits of mdm, however it does allow the roll out of mobile configuration updates to devices infield.

  1. No trackbacks yet.

Leave a comment