PKI with Smart Card and Encryption Solution

New Contributor III

I know this has been discussed before but with new government regulations we are being required to go 2 factor authentication and we need to maintain disk encryption on our systems. Does anyone have a full solution or best practices for this. After requiring smart cards we can't enroll file vault users without error and encryption is not syncing AD password for existing systems.


Valued Contributor

If you're doing this to satisfy HSPD-12 requirements, take a look at Centrify or Thursday. Neither are free, but both work well, and are fairly widely used in .gov to satisfy the requirement.

As for FileVault - our solution is to have a "FileVault User" account with severely restricted permissions, and a password known to the user. They enter that to get past the FV login, but it is set to stop at the normal login window, at which point they insert their CAC and type the PIN to get to the finder.

Valued Contributor III

FV2 will not work with with cert only based authentication as it's reliant on username / password auth to work. This may change with the advent of APFS. Watch this space.

This entire subject is in massive flux at the moment. A lot of the original backend technologies that macOS used have either been removed or depreciated in favour of new API's that (currently) have almost no manufacturer support.

The single FV user is a solution i've seen elsewhere but it is a little inelegant. Also means you have a single password that gets you into the machine and any other on your estate, which is a big no no in most security conscious organisations even if it only dumps you out at the login window.

I'm working on something for this but it's not even close for release at this moment. I'll give you a clue, it involves hidden created local user accounts for FV2 that otherwise cannot be logged into.

Valued Contributor III

Proof of concept code. I take zero responsibility for this as it's totally untested and will require modification for your environment.


# Create CS FV2 unlock only user - Proof of Concept Code

# Variables here

# Check for FV2 been enabled

fv2status=$( fdesetup status )

if [ "$fv2status" != "FileVault is On." ];
    echo "FV2 not fully enabled. Quitting."
    exit 0

# Start by disabling FV2 passthrough login

defaults write /Library/Preferences/ DisableFDEAutoLogin -bool YES

# Find user PID from smart card.

# Code from sc_auth. Spits out a bunch of hashes in the following format:
# 1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZB2BE name.surname (A123456)

  HOME=/no/where /usr/bin/security dump-keychain |
  awk -v RE="$string" '
        /^    0x00000001/       {
                if (matched = ($2 ~ RE)) { name=$0; sub("^.*<blob>="", "", name); sub(""$", "", name); count++; }}
        /^    0x00000006/       {
                if (matched) { hash=$2; sub("<blob>=0x", "", hash); print hash, name; }}
  HOME=/no/where /usr/bin/security dump-keychain |
  awk -v RE="$string" '
        /^    0x01000000/       {
                if (matched = ($2 ~ RE)) { name=$0; sub("^.*<blob>="", "", name); sub(""$", "", name); count++; }}
        /^    0x06000000/       {
                if (matched) { hash=$2; sub("<blob>=0x", "", hash); print hash, name; }}

# Take the hash report. Strip out first two fields, the () characters and the first letter. This will be the unlock account.
# Can't use the full text at the end of the code as this will be the AD account created later from the card info. Two accounts One space!

newuser=$( echo $hash | awk '{gsub(/[;()'']/," "); print substr($3,2);}' )

# Prompt user with CocoaDialog for a device unlock password. Reference name we gathered earlier.

entry=$( $cdialogbin inputbox --title "Password" --icon-file "$lockscreenlogo" --informative-text "Please enter your password:" --text $hardcode --string-output --button1 "Ok" )
password=$( echo $entry | awk '{ print $2 }' )

# Find the last UIDs for users and groups used and go one higher for new account.

lastgroupuid=$( dscl . -list /Groups PrimaryGroupID | awk '{print $2}' | sort -n | tail -n1 )
groupuid=$( expr $lastgroupuid + 1 )

lastuseruid=$( dscl . -list /Users UniqueID | awk '{print $2}' | sort -n | tail -n1 )
useruid=$( expr $lastuseruid + 1 )

# Create a user group for this user

dscl . -create /Groups/FV2user
dscl . -create /Groups/FV2user PrimaryGroupID "$usergroup"

# Create the new user, hide it and add it to the group

dscl . -create /Users/$newuser
dscl . -create /Users/$newuser UserShell /bin/nologin
dscl . -create /Users/$newuser RealName "$newuser"
dscl . -create /Users/$newuser UniqueID "$useruid"
dscl . -create /Users/$newuser PrimaryGroupID "$groupuid"
dscl . -create /Users/$newuser IsHidden 1
dscl . -passwd /Users/$newuser $password

# Write out an FV2 plist so we can add this user to the FV2 users list

fv2xml='<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">

echo $fv2xml > /private/tmp/fv.plist

# Now add user to the FV2 authorised users list

fdesetup add -inputplist < /private/tmp/fv.plist

# Clean up

rm /private/tmp/fv.plist