If you like to use long random passwords for things like encrypted disk images (created in Disk Utility) you may have noticed Apple make this rather difficult. Simply put, Apple decided to block the pasting of passwords when creating disk images. Some people suggest this was to make brute force attacks on these encrypted files more difficult, but in reality that doesn’t stand up to reason. Using the command line passwords can be pasted, and it is much easier to launch a brute force attack at the command line level than through a GUI. But I digress.
Typing out long random passwords manually is a pain. This encourages people to use short passwords that are easier to remember and/or type. So the effect of Apple’s move is that it may encourage people to use less secure passwords, all for zero gain. Here’s how to resolve this.
You’ll need to fire up AppleScript Editor. Paste in the following script:
tell application "System Events" to tell process "SecurityAgent" set value of text field 1 of window 1 to (the clipboard) if exists (text field 2 of window 1) then set value of text field 2 of window 1 to (the clipboard) end if click button 2 of window 1 end tell
You can remove the second to last line if you don’t want the password dialog to be submitted automatically. The script is designed to handle setting the password when creating a disk image (which requires entering it twice), and the submission of the password when opening the disk image (which only requires entering it once).
Save the script. Next you need to set up a way to trigger and run it easily.
UPDATE: A much better script
UPDATE [March 19, 2015]: Below is an improved script I have pieced together. It has the following features:
- It will detect and not run if the SecurityAgent isn’t actually running (i.e. you’re not being asked to enter a password by the SecurityAgent).
- It will actually do the copying of the password from 1Password 5. If you use another password manager, you will need to make the necessary changes to the variable passManager. You may also need to edit the menu commands your password manager uses for copying the password from the current item. See the comments in the script.
- It will check if you are creating a new password and, if you are, it will let you specify if you wish to save that password to your keychain.
- … and it has a few other minor bells and whistles that old script didn’t have.
-- Script from best-mac-tips.com set appName to "SecurityAgent" set passApp to "1Password 5" (* set this to the name of your password manager *) tell application "System Events" if not (exists window 1 of process appName) then -- test if SecurityAgent window exists set answer to display dialog "The password dialog was not found. Please start it again if necessary. (This window will close in 5 seconds)" buttons {"Ok"} default button "Ok" giving up after 5 return -- abort if SecurityAgent window does not exist else tell application "System Events" set position of window 1 of process appName to {20, 250} -- move SecurityAgent window out of the way end tell display alert "Alert" message "Click OK to initiate copy/paste of password into " & appName & " from " & ¬ passApp & ", or click Cancel to abort." buttons {"Cancel", "OK"} cancel button "Cancel" default button "OK" end if end tell tell application "System Events" set question to display dialog "Are you creating a new password?" buttons {"No", "Yes"} default button "No" set newpass to button returned of question if newpass is equal to "Yes" then set question to display dialog "Do you wish to store this password in your OS X Keychain? (since you use " & passApp & ", the chances are you don't want to)" buttons {"No", "Yes"} default button "No" set keychainPref to button returned of question else set keychainPref to "No" end if end tell tell application "System Events" to set the clipboard to "" set testResult to "" repeat until testResult is true activate application passApp tell application "System Events" set lengthTest to null repeat until lengthTest is equal to true set the clipboard to "" set passData to "" tell application "SystemUIServer" if newpass is equal to "No" then set answer to display dialog "Make sure correct 1Password item is actively selected (i.e. click it again if it was previously selected, so it is actively highlighted)." & return & return & "Then click 'Continue' to proceed." buttons {"Cancel", "Continue"} cancel button "Cancel" default button "Continue" else if newpass is equal to "Yes" then set answer to display dialog "Use " & passApp & " to generate a new password. Save the item. Then make sure that new item is actively selected (i.e. click it again after you save it, so it is actively highlighted)." & return & return & "Only then, click 'Continue' to proceed." & return & return & "(Note: You can move this window out of your way if you need to)" buttons {"Cancel", "Continue"} cancel button "Cancel" default button "Continue" end if end tell tell process passApp (* If you are not using 1Password, you may need to change the menu item clicks, below, to whatever is correct in your particular password manager *) click menu item "copy password" of menu "item" of menu bar 1 delay 0.5 -- Give it a moment to do what it needs to do set passData to the clipboard set lengthTest to my testPassword(passData) if lengthTest is false then beep 2 display dialog "The password is empty, click 'Ok' to try again." & return & return & "Or click 'Cancel' to abort" buttons {"Cancel", "Ok"} cancel button "Cancel" default button "Cancel" else if lengthTest is true then end if end tell end repeat tell application "System Events" tell process appName set value of text field 1 of window 1 to passData if exists (text field 2 of window 1) then set value of text field 2 of window 1 to passData end if if exists checkbox "Remember password in my keychain" of window 1 then if keychainPref is equal to "Yes" then if value of checkbox "Remember password in my keychain" of window 1 is 0 then click checkbox "Remember password in my keychain" of window 1 end if else if keychainPref is equal to "No" then if value of checkbox "Remember password in my keychain" of window 1 is 1 then click checkbox "Remember password in my keychain" of window 1 end if end if else if exists checkbox "Remember this password in my keychain" of window 1 then if keychainPref is equal to "Yes" then if value of checkbox "Remember this password in my keychain" of window 1 is 0 then click checkbox "Remember this password in my keychain" of window 1 end if else if keychainPref is equal to "No" then if value of checkbox "Remember this password in my keychain" of window 1 is 1 then click checkbox "Remember this password in my keychain" of window 1 end if end if end if delay 0.5 (* gives a moment for user to see what's going on *) if exists button "OK" of window 1 then click button "OK" of window 1 else if exists button "Unlock" of window 1 then click button "Unlock" of window 1 end if set testResult to my testSuccess(appName) end tell end tell end tell end repeat set soundName to "Hero" display notification "Secure password successfully pasted" with title "Secure Password Paster" sound name soundName on testSuccess(appName) delay 3 tell application "System Events" if not (exists window 1 of process appName) then display dialog "Password has been pasted. You're all done. This window will close in 5 seconds" with title "Process complete" buttons {"OK"} default button "OK" giving up after 5 return true else if exists window 1 of process appName then set position of window 1 of process appName to {20, 250} set soundName to "Basso" display notification "Password mismatch or error" with title "Secure Password Paster" subtitle "Try again" sound name soundName display dialog "ERROR: The password is wrong, or doesn't match." & ¬ return & return & "Click 'Quit' if you wish to abort, or 'Continue' to try again" buttons {"Quit", "Continue"} cancel button "Quit" default button "Continue" return false else return "Error" end if end tell end testSuccess on testPassword(passData) -- display dialog "passData equals: " & passData if the passData is null or the passData is "" then return false else return true end if end testPassword
The simpler script I posted on March 8th, 2015 is below. It’s without all the tricks of the March 15th script, but may suit your needs better if you don’t want so much automation.
-- Script from best-mac-tips.com set appName to "SecurityAgent" set passApp to "1Password 5" (* set this to the name of your password manager *) tell application "System Events" if not (exists window 1 of process appName) then -- test if SecurityAgent window exists return -- abort if SecurityAgent window does not exist end if end tell tell application "System Events" set position of window 1 of process appName to {10, 10} -- move SecurityAgent window out of the way end tell tell application passApp activate -- bring 1Password to the forefront, run it if not running end tell tell application "System Events" tell application "SystemUIServer" set answer to display dialog "Make sure correct 1Password item is actively selected (i.e. click it again if it was previously selected), then click “Continue” to proceed." buttons {"Continue"} end tell tell process passApp (* If you are not using 1Password, you may need to change the menu item clicks, below, to whatever is correct in your particular password manager *) click menu item "copy password" of menu "item" of menu bar 1 delay 1 set appData to the clipboard end tell tell application "System Events" tell process appName set value of text field 1 of window 1 to appData if exists (text field 2 of window 1) then set value of text field 2 of window 1 to appData click button 1 of window 1 else click button 2 of window 1 end if end tell end tell end tell
If you would like to ensure the “Remember password in my keychain” is never ticked, the last TELL statement (tell application “system events”) in the above March 8th script can be changed to this:
tell application "System Events" tell process appName set value of text field 1 of window 1 to appData if exists (text field 2 of window 1) then set value of text field 2 of window 1 to appData if value of checkbox "Remember password in my keychain" of window 1 is 1 then click checkbox "Remember password in my keychain" of window 1 end if set value of checkbox 1 of window 1 to 0 delay 1 (* gives a moment to see what's going on *) click button 1 of window 1 else if value of checkbox "Remember password in my keychain" of window 1 is 1 then click checkbox "Remember password in my keychain" of window 1 end if delay 1 (* gives a moment to see what's going on *) click button 2 of window 1 end if end tell end tell
Shortcut to the script
You will also need to tick “Enable access for assistive devices” in the System Preferences. There’s an option for that in Accessibility preferences:
You should now be able to copy and paste complex passwords from whatever you use to generate and store your passwords. I use, and highly recommend, a great app called 1Password.
Update for Mavericks and Yosemite
Accessibility options have changed in recent versions of OS X (starting with Mavericks, as far as I can determine). You will need to specifically add your preferred shortcut app to the Accessibility preferences. For instance, you may need to add Alfred, or add Automator. This will depend on which you decide to utilise.
Further Yosemite automation issues:
Further testing on my system indicates Yosemite treats an unsigned script as changed (and therefore as a potential security risk) each time you run it. This makes things complicated for those who wish to through a few scripts in here and there. Because every time you run it you will need to grant it Accessibility permissions.
I know of a few options to work around this. One is to save my script using Script Editor (formally AppleScript Editor) as an application, and you will need to sign it when you do that. That means generating a Certificate Authority in Keychain, and use that to sign your applet. Alternatively, you can follow the information provided by Apple here. That’s the way I recommend going about it. UPDATE: Turns out that info is for Mavericks, and the PLIST file it links to does not exist. I will have to post a solution later. I’ve run out of time on this.
The script provided here on macosxautomation.com might also be useful.
Using an Automator service to run the “paste password” script
You can use Automator to create a system service that will run the script. Once you save that new service, you’ll be able to assign a keyboard shortcut to it using the System Preferences in OS X.
- Run Automator.app
- Create a new Service
- Set the service to receive no input. You’ll find this at the top of the actions pane, “Service receives…”
- Add a “Run AppleScript” action
- Paste your script into the action (keeping the “on run” and “end run” lines at the beginning and end)
- Save the service
- Open the System Preferences, and bring up the Keyboard Preferences
- Select the Keyboard Shortcuts pane
- Select Services in the list on the left.
- You should find your new service near the bottom of the list of available services, in the General section. Make sure it is ticked, and add a keyboard shortcut to it (using a key combination that is not likely to be already in use).
Using Alfred to run the script
If you have Alfred (with the Powerpack) you can use it to run the above script.
- Create a new blank workflow in Alfred
- Add in the Trigger called “Hotkey“
- Assign a hotkey shortcut (something that’s not already in use)
- Add in the Action “Run Script“
- Select script language, “/usr/bin/osascript”
- Paste the script (from above) into the script area.
Using Quicksilver
A free alternative to Alfred is Quicksilver. You can use it to run a script also.
Simply create a new Trigger in Quicksilver. Tell it to run the script you created above (you’ll need to locate the script in the folder you saved it to).
Edit the Trigger and set a hotkey.
Make sure you added Quicksilver to the Privacy system preferences under Accessibility (see above).
Using Fastscripts
Another great way to run scripts, via shortcuts, is the app called FastScripts. For loading in up to ten shortcuts it is free. It’s around $10 if you need more.
Using the command line instead of a script
You can also use the command line (via Terminal.app) to mount your disk image. Here’s the command to use:
hdiutil attach /path/to/imagefile -stdinpass
If the image file has a long path, you can simply type in hdiutil attach and then drag the file from finder into the Terminal. Then add -stdinpass and hit Return.
You can also use the command line for creating an encrypted disk image, and doing it this way will allow you to paste your password in.
Use these commands:
cd /path/to/where/you/want/the/image hdiutil create -size thesize -encryption -type SPARSEBUNDLE -fs HFS+ thename
You’ll need to replace “thesize” and “thename”. The size is the maximum size of the sparsebundle. It won’t take up this amount of space until you actually add that amount of data into the image, but this will determine the maximum amount of space it is allowed to take. The name is just the name of the image file. The actual volume inside the image you can name from within Finder, once you’ve mounted the image.
When doing the cd command, if the path is a long one, remember you can drag the folder from Finder into the terminal, and the path will automagically appear.
Thanks for the script. Great idea!
This script no longer works on Yosemite. Any ideas on how it could be updated?
Hi Jake. I’ve not installed Yosemite yet. Will likely be a few months before I do. So I may not get around to looking for a solution to this until then. If you find one yourself, please post it here. Cheers… Jonathan