Skip to content

Instantly share code, notes, and snippets.

@brodieG
Last active February 26, 2018 17:43
Show Gist options
  • Save brodieG/5550813d9a9fc1f7466a29d5abacb5d8 to your computer and use it in GitHub Desktop.
Save brodieG/5550813d9a9fc1f7466a29d5abacb5d8 to your computer and use it in GitHub Desktop.
Use Troy Hunt's Have I Been Pwned Database from R
# Test your passwords against the "Pwned Passwords" V2 database
# as described in <https://www.troyhunt.com/ive-just-launched-pwned-passwords-version-2/>
#
# USE AT YOUR OWN RISK. I MAKE NO GUARANTEES THAT THIS CODE
# PROTECTS YOUR PASSWORDS.
#
# requires `digest` package (thanks @eddelbuettel)
#
# This code is published under the GPL-2 License
# <https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html>
# Copyright 2018 - Brodie Gaslam
#
# Copy and paste into your terminal (after carefully reviewing, of course),
# or get the raw url and `source(<url>, echo=TRUE)`
pwned_get_pw <- function() readline('Type Password and then hit ENTER: ')
pwned_as_sha1 <- function(pw) digest::digest(pw, algo='sha1', serialize=FALSE)
pwned_url <- function(pw.sha1=pwned_as_sha1(pwned_get_pw()))
sprintf("https://api.pwnedpasswords.com/range/%s", substr(pw.sha1, 1, 5))
# NOTE: if you pass type a string for `x` instead of using NULL
# that string will be stored in plain text in your R history
have_i_been_pwned <- function(x=NULL) {
pw <- if(is.null(x)) pwned_get_pw()
else if(!is.character(x) || length(x) != 1) stop("Invalid input")
else x
pw.sha1 <- pwned_as_sha1(pw)
url <- pwned_url(pw.sha1)
res <- readLines(url, warn=FALSE)
if(length(res)) {
hash.match <- sprintf("^%s:(\\d+)", toupper(substr(pw.sha1, 6, 40)))
res.sub <- sub(hash.match, "\\1", res)
sum(suppressWarnings(as.integer(res.sub)), na.rm=TRUE)
} else 0L
}
# If output != 0 you have been pwned
# You can pass a string to `have_i_been_pawned`, but better to leave
# the input missing and type in pwd via `readline` to avoid having
# your password in plain text in .Rhistory
have_i_been_pwned()
@tall-lantern
Copy link

Thanks for this!
Above script breaks on line 30 with R 3.1.1 with the following error:

Error in file(con, "r") : cannot open the connection
In addition: Warning message:
In file(con, "r") : unsupported URL scheme

I reverted to the following method of reading URLs and it does the read the url fine. Though further cleanup needs to be done to clean the url output for matching to the password query.

library(RCurl)
data=getURL(url)

Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment