3

I am trying to move passwords that are currently hard coded in R code into "encrypted"/encoded file on disk.

I would like to do it in similar way as SAS PWENCODE procedure does ( http://support.sas.com/documentation/cdl/en/proc/63079/HTML/default/viewer.htm#n0ii0upf9h4a67n1bcwcesmo4zms.htm , ODBC Password Security in SAS).

Is there something similar in R? What approaches do you use to store passwords in R for the code that needs to be run periodically without human intervention in the form of typing passwords?

EDIT: Forgot to mention: the only thing that looks similar to me is RCurl::base64() .

Community
  • 1
  • 1
Samo
  • 2,065
  • 20
  • 41
  • Very similar question: http://stackoverflow.com/q/6101605/602276 – Andrie Jul 13 '12 at 21:40
  • @Andrie Thnx. Yes, I saw that question, but no answer directly answers my question, I guess. If answers under question you mention is as good as it gets in R I am fine, as long as I know and stop searching for SAS like PWENCODE... – Samo Jul 13 '12 at 21:47

1 Answers1

2

I've outlined my method of achieving this on Windows in my blog post below:

http://www.gilfillan.space/2016/04/21/Using-PowerShell-and-DPAPI-to-securely-mask-passwords-in-R-scripts/

Essentially...

  1. Ensure you have enabled PowerShell execution.

  2. Save the following text into a file called EncryptPassword.ps1:

    # Create directory user profile if it doesn't already exist.
    $passwordDir = "$($env:USERPROFILE)\DPAPI\passwords\$($env:computername)"
    New-Item -ItemType Directory -Force -Path $passwordDir
    
    # Prompt for password to encrypt
    $account = Read-Host "Please enter a label for the text to encrypt.  This will be how you refer to the password in R.  eg. MYDB_MYUSER
    $SecurePassword = Read-Host -AsSecureString  "Enter password" | convertfrom-securestring | out-file "$($passwordDir)\$($account).txt"
    
    # Check output and press any key to exit
    Write-Host "Press any key to continue..."
    $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
    
  3. Execute the script above (right click > Run with PowerShell), provide a meaningful name for the password, and type in the password. You can now verify that the password has been encrypted by checking the file in %USERPROFILE%/DPAPI/passwords/[PC NAME]/[PASSWORD IDENTIFIER.txt]

  4. Now run the following code from within R (I have this function saved in an R script that I source at the start of each script.

    getEncryptedPassword <- function(credential_label, credential_path) {
      # if path not supplied, use %USER_PROFILE%\DPAPI\passwords\computername\credential_label.txt as default
      if (missing(credential_path)) {
        credential_path <- paste(Sys.getenv("USERPROFILE"), '\\DPAPI\\passwords\\', Sys.info()["nodename"], '\\', credential_label, '.txt', sep="")
      }
      # construct command
      command <- paste('powershell -command "$PlainPassword = Get-Content ', credential_path, '; $SecurePassword = ConvertTo-SecureString $PlainPassword; $BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword); $UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR); echo $UnsecurePassword"', sep='')
      # execute powershell and return command
      return(system(command, intern=TRUE))
    }
    
  5. Now when you need to supply a password in R, you can run the following command instead of hardcoding / prompting for the password:

    getEncryptedPassword("[PASSWORD IDENTIFIER]")
    

    For example, instead of running the ROracle command:

    dbConnect(driver, "MYUSER", "MY PASSWORD", dbname="MYDB")
    

    You can run this instead (the identifier I supplied in Step 3 is "MYUSER_MYDB":

    dbConnect(driver, "MYUSER", getEncryptedPassword("MYUSER_MYDB"), dbname="MYDB")
    
  6. You can repeat Step 3 for as many passwords as are required, and simply call them with the correct identifier in Step 5.
Community
  • 1
  • 1
Josh Gilfillan
  • 4,348
  • 2
  • 24
  • 26