2016-08-22 133 views
0

我有一個存儲在純文本文件中的密碼。我想以某種方式混淆它,以防有人在看我的顯示器。R中的混淆字符串

理想情況下,我想用另一個默認字符串(比如「123」)加密一個密碼,並獲得密碼的混淆版本。然後,當我在代碼中需要密碼時,我想用相同的字符串「123」解密密碼。混淆密碼和正常密碼的長度不同也是好的。

所以,邏輯應該是:

encrypt(password, "123") -> obf_string 
decrypt(obf_string, "123") -> password 

我怎樣才能做到這一點?

P.S.我知道這不是安全的,但這是我現在想要的。

+0

Andrie德弗里斯寫了關於這個問題的好文章:https://www.r-bloggers.com/securely-storing-your-secrets-in-r-code/ – NJBurgo

+0

雖然第一篇文章更有用:http://blog.revolutionanalytics.com/2015/11/how-to-store-and-use-authentication-details-with-r.html – NJBurgo

+1

如果您正在處理密碼,請勿加密/解密;相反,使用散列。例如'digest :: digest(password)'返回一個散列,你可以放心地輸入代碼。當用戶輸入密碼時,您將其與「正確」的密碼進行匹配,因此您不必解密。看到維基頁面https://en.wikipedia.org/wiki/Cryptographic_hash_function – nicola

回答

0

一個快速的方法來混淆是通過隨機數生成,這裏我嘗試:

encrypt <- function(password, string){ 
     set.seed(password) 
     encr <- round(runif(nchar(string), 0, 9)) 
     y <- as.integer(substring(string, seq(nchar(string)), seq(nchar(string)))) + encr 
     return(y) 
} 

decrypt <- function(password, string){ 
     set.seed(password) 
     encr <- round(runif(nchar(string), 0, 9)) 
     y <- paste0(string - encr, collapse="") 
     return(y) 
} 

你的字符串是如1984。您只需選擇一個密碼,例如2016

> encrypt(2016, "1984") 
[1] 3 10 16 5 

你給他們encrypt(),函數返回你的字符串的大小相同的數值向量。找回列使用decrypt()你的密碼和矢量:

> decrypt(2016, c(3,10,16,5)) 
[1] "1984" 

一個不太懂事的替代,其還允許文本連接,通過base64編碼/解碼,使用base64enc包:

install.packages("base64enc") 
library(base64enc) 
base64encode(c(2,0,0,6)) 
base64decode("AgAABg==") 
+1

好主意!是否可以取消安裝額外的軟件包以便在加密時立即獲取字符串? –

+0

我看到'set.seed'只能解釋整數,而不是字符串。任何方式來改變它? –

+0

@zaph'base64'確實很標準:https://en.wikipedia.org/wiki/Base64 – 000andy8484

1

跟進@zach評論,這個程序在攻擊的情況下是不安全的。這是特別有用的是你想混淆一個字符串(例如,從某人經過並看着屏幕),這個問題並不暗示安全性。

這是我的功能版本我以前的答案報道還接受帶有數字和字母的字符串:

obfuscate <- function(password, string){ 
     set.seed(password) 
     vec <- substring(string, seq(nchar(string)), seq(nchar(string))) 
     encr <- y <- vector("list",length(vec)) 
     letters <- rep(letters,2) # prolongue letters sequence 
     for (i in 1:length(vec)){ 
       ifelse(is.numeric(vec[i]),    # extracting encryption numbers 
         encr[[i]] <- round(runif(1, 0, 9)), # if numeric 
         encr[[i]] <- round(runif(1, 0, 26))) # if letters 

       ifelse(!is.na(as.numeric(vec[i])) , # encrypting 
         y[[i]] <- as.numeric(vec[i]) + encr[[i]],     # if numeric 
         y[[i]] <- letters[which(letters==vec[i])[1] + encr[[i]]]) # if letters 
     } 
     return(unlist(y)) 
} 

reveal <- function(password, y){ 
     set.seed(password) 
     for (i in 1:length(y)){ 
       ifelse(is.numeric(y[i]),    # extracting encryption numbers 
         encr[[i]] <- round(runif(1, 0, 9)), # if numeric 
         encr[[i]] <- round(runif(1, 0, 26))) # if letters 
       ifelse(!is.na(as.numeric(y[i])) , # encrypting 
         y[[i]] <- as.numeric(y[i]) - encr[[i]],     # if numeric 
         y[[i]] <- letters[which(letters==y[i])[1] - encr[[i]]]) # if letters 
     } 
     return(paste0(unlist(y), collapse="")) 
} 

下面是一個例子:

> obfuscate(2016,"a6b8") 
[1] "f" "10" "x" "11" 
Warning messages: 
1: In ifelse(!is.na(as.numeric(vec[i])), y[[i]] <- as.numeric(vec[i]) + : 
    NAs introduced by coercion 
2: In ifelse(!is.na(as.numeric(vec[i])), y[[i]] <- as.numeric(vec[i]) + : 
    NAs introduced by coercion 

注意,警告的數量是等於非數字字符的數量。如in this SO question所述,這可以用suppressWarnings()來抑制。我的首選是總是表達R警告。

> reveal(2016,c("f","10","x","11")) 
[1] "a6b8" 
Warning messages: 
1: In ifelse(!is.na(as.numeric(y[i])), y[[i]] <- as.numeric(y[i]) - : 
    NAs introduced by coercion 
2: In ifelse(!is.na(as.numeric(y[i])), y[[i]] <- as.numeric(y[i]) - : 
    NAs introduced by coercion 
+0

雖然發明enctyption很有趣,但再次使用它是一個不好的主意:[「Schneier法則」](https://www.schneier.com/blog/archives/2011/04/schneiers_law.html):任何人,從對最好的密碼專家來說,最無能爲力的業餘愛好者可以創建一種他自己無法破解的算法。此外,不能保證'set.seed'在系統之間或軟件版本之間是相同的。 – zaph

+1

我們得到了@ zaph的觀點,但是Sergey需要「以某種方式混淆」一個字符串,不要重新創建謎題機器。安全不涉及這個具體問題。 – 000andy8484

+0

您將函數命名爲「encrypt」和「decrypt」。由於它使用密鑰,它似乎有資格作爲加密。另外,不知道'r',一般的警告信息都不是好事。 – zaph