2017-03-02 71 views
1

我試圖從一個受密碼保護的文件讀取數據庫的密鑰爲R並將其轉化爲原材料,具體如下:[R通過包含從文件到charToRaw反斜線的字符串不轉義

假設我關鍵是\[email protected]\xErd\xD5b\x1bs。我的目標是獲得相同的原始密鑰我得到直接傳遞密鑰時作爲字符串到charToRaw功能:

rawkey1 <- charToRaw("\[email protected]\xErd\xD5b\x1bs") 

> rawkey1 
[1] 0b 40 0e 72 64 d5 62 1b 73 

我可以在.csv文件保存這一點,並在與R讀回:

savemykey <- data.table(keyinbytes = "\[email protected]\xErd\xD5b\x1bs") 

write.csv(savemykey, file = "My_key.csv") 

mykey <- read.csv("My_key.csv", header = TRUE, stringsAsFactors = FALSE) 

我然後可以將其轉換爲原始和它產生所期望的結果:從直接傳遞給charToRaw函數產生

> rawkey2 = charToRaw(mykey$keyinbytes) 
> rawkey2 
[1] 0b 40 0e 72 64 d5 62 1b 73 

原始鍵並從包含密鑰的csv文件中讀取相同:

> rawkey1 == rawkey2 
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE 

到目前爲止這麼好。唯一的問題是密鑰是包含敏感信息的數據庫的關鍵,所以我想將其存儲在受密碼保護的文件中。

我能想到的唯一方法就是使用Microsoft Excel(回讀excel.link包並提供密碼作爲參數);然而,似乎在創建.xlsx文件反斜線被解釋爲逃逸,當他們讀回這將導致不正確的轉換,從性格到原料:

library(xlsx) 
write.xlsx2(savemykey, file = "My_key.xlsx", append = FALSE) 

然後我打開Microsoft Excel文件,分配密碼「輸入mypassword」,保存並與excel.link包讀回以:

library(excel.link) 
mykey <- xl.read.file("My_key.xlsx", xl.sheet = 1, password = "mypassword") 

# Re-running the conversion: 
rawkey3 = charToRaw(mykey$keyinbytes) 

> rawkey3 
[1] 3f 40 3f 72 64 d5 62 3f 73 

如果我比較這結果與第一個關鍵,它不匹配:

> rawkey3 == rawkey1 
[1] FALSE TRUE FALSE TRUE TRUE TRUE TRUE FALSE TRUE 

這是因爲在Microsoft Excel文件讀取時,R已經解釋反斜線逃逸,逃逸字符跟隨他們,並用它們替換,見下文「?」:根據我所

# Key as assigned object in R: 
> savemykey$keyinbytes 
[1] "\[email protected]\016rdÕb\033s" 

# Key read in from Microsoft Excel file: 
> mykey$keyinbytes 
[1] "[email protected]?rdÕb?s" 

至今嘗試過,似乎如果我將密鑰保存爲可以保存爲純文本(.csv,.txt或直接在R腳本中並將其源文件保存)的任何文件類型,則會將密鑰讀回到R中正確評估反斜槓並將其轉換爲正確的原始字節模式。但是,我一直無法找到任何密碼保護純文本文件/ .csv或R腳本的方法。

我想要麼:

  • 找到的密碼保護純文本格式的文件,將保留關鍵中的反斜槓的評價方式讀回R和用於其在方法讀取時以密碼作爲參數,或;

  • 找到一種方法來讀取密碼保護的Microsoft Excel文件中的密鑰,而不用轉義反斜槓。

任何想法如何做到這一點將不勝感激。

+0

我在Windows 7操作系統中使用帶有RStudio 1.0.136的(64位)R 3.3.2。我認爲我的Microsoft Office程序可能是32位的,因爲在查詢MS Access數據庫時(如果有任何相關性的話),我必須調用32位R。 –

回答

0

我的確找到了一種創建加密文本文件的方法(可以是數據,也可以是一個稍作修改的R腳本)。創建加密文件的腳本,然後在使用摘要包進行讀取後解密它,由Stephane Doyen在此創建:https://github.com/sdoyen/r_password_crypt

這種工作方式如下:

# Load libraries 

# This does the encryption and decryption 
require(digest) 

# This allows users to enter a password securely with a masked widget 
require(getPass) 

# I'll put the details I want to encrypt into a data.table 
require(data.table) 

創建並輸入密碼(長度必須在16個字母數字字符。例如: 'myfavouritepw123' 的倍數):

mypw <- charToRaw(getPass("Enter the password for your login details file:")) 

負載斯特凡的寫。 aes和read.aes功能:

# To encrypt and password protect a file: 
write.aes <- function(df,filename, key) { 
    require(digest) 
    zz <- textConnection("out","w") 
    write.csv(df,zz, row.names=F) 
    close(zz) 
    out <- paste(out,collapse="\n") 
    raw <- charToRaw(out) 
    raw <- c(raw,as.raw(rep(0,16-length(raw)%%16))) 
    aes <- AES(key,mode="ECB") 
    aes$encrypt(raw) 
    writeBin(aes$encrypt(raw),filename) 
} 


# To decrypt the file with a password after reading it back in: 
read.aes <- function(filename,key) { 
    require(digest) 
    dat <- readBin(filename,"raw",n=1000) 
    aes <- AES(key,mode="ECB") 
    raw <- aes$decrypt(dat, raw=TRUE) 
    txt <- rawToChar(raw[raw>0]) 
    read.csv(text=txt, stringsAsFactors = F) 
}  

創建您要加密的文件:

注意:使用write.aes加密會導致'\',並且前面的字符會被誤解。爲避免這種情況,將密鑰轉換爲raw並將原始字節保存爲單個字符串。使用paste0collapse將代表每個字節的字符粘貼在一起(sep將不起作用)。

write.aes(df = mysecretlogin1, filename = "mysecretkey.txt", key = mypw) 

文件讀回,和你的密碼解密:

mysecretlogin1 <- data.table(keyinbytes = paste0(charToRaw("\[email protected]\xErd\xD5b\x1bs"), collapse = " ")) 

使用您之前爲重點創建的密碼寫data.table與write.aes加密文件

mypw <- charToRaw(getPass("Enter the password for your login details file:")) 

mysecretlogin2 <- data.table(read.aes(filename = "mysecretkey.txt", key = mypw)) 

檢查導出和導入的文件是相同的:

> mysecretlogin1 == mysecretlogin2 
    keyinbytes 
[1,]  TRUE 

要以原始形式使用密鑰,可以使用此函數將字符串轉換回原始字節(在每個字節允許它們傳遞到不帶引號的列表作爲原始向量之前添加「0x」):

makeraw <- function(characterstring) { 
    mystring <- strsplit(characterstring, " ") 
    mystring <- lapply(mystring, function(x) paste0("0x", x)) 
    mystring <- as.raw(unlist(mystring)) 
    mystring 
} 

應用功能:

myrawkey <- makeraw(mysecretlogin2$keyinbytes) 

檢查它一直:

> myrawkey 
[1] 0b 40 0e 72 64 d5 62 1b 73 
> str(myrawkey) 
raw [1:9] 0b 40 0e 72 ... 
> is.raw(myrawkey) 
[1] TRUE 

的 '鑰匙'(沒有雙關語INTE )在這個解決方案中避免了通過將密鑰存儲爲(漂亮的字母數字)原始字節的字符串版本而將反斜槓誤解爲轉義字符的整個問題。