Làm thế nào để chuyển đổi String
sang SecureString
?
Làm thế nào để chuyển đổi String
sang SecureString
?
Câu trả lời:
Bạn không. Toàn bộ lý do để sử dụng đối tượng SecureString là để tránh tạo một đối tượng chuỗi (được tải vào bộ nhớ và giữ ở đó trong bản rõ cho đến khi thu gom rác). Tuy nhiên, bạn có thể thêm các ký tự vào SecureString bằng cách nối thêm chúng.
var s = new SecureString();
s.AppendChar('d');
s.AppendChar('u');
s.AppendChar('m');
s.AppendChar('b');
s.AppendChar('p');
s.AppendChar('a');
s.AppendChar('s');
s.AppendChar('s');
s.AppendChar('w');
s.AppendChar('d');
*****
AppendChar
không thực thi cho đến khi chạy, vì vậy những ký tự đó vẫn có thể được đọc từ IL, đúng không? Có lẽ một số obfuscation thời gian biên dịch cũng sẽ giúp ... đó là, nếu bạn là mật khẩu mã hóa cứng.
Cũng có một cách khác để chuyển đổi giữa SecureString
và String
.
1. Chuỗi để SecureString
SecureString theSecureString = new NetworkCredential("", "myPass").SecurePassword;
2. SecureString to String
string theString = new NetworkCredential("", theSecureString).Password;
Đây là liên kết
SecureString
nếu mã của bạn tạo một string
đối tượng với giá trị bạn muốn bảo mật. Mục tiêu của việc SecureString
tránh để có chuỗi trong bộ nhớ được quản lý, vì vậy kẻ tấn công kiểm tra bộ nhớ đó có thể phát hiện ra giá trị bạn muốn ẩn. Vì hàm NetworkCredential
tạo mà bạn đang gọi yêu cầu một chuỗi, đó không phải là cách để đi ... Chắc chắn, mã của bạn là một cách dễ dàng để chuyển đổi sang và từ SecureString, nhưng sử dụng nó giúp mã của bạn an toàn như sử dụng một cách đơn giảnstring
SecureString
khi làm việc với một số thư viện. Và hãy trung thực ở đây, nếu ai đó đang tích cực quét bộ nhớ ứng dụng của bạn thì bạn đã bị mất. Ngay cả khi bạn đã sử dụng SecureString một cách chính xác, điều mà tôi chưa từng thấy, sẽ có một dữ liệu có giá trị khác để trích xuất.
Phương pháp dưới đây giúp chuyển đổi chuỗi thành chuỗi an toàn
private SecureString ConvertToSecureString(string password)
{
if (password == null)
throw new ArgumentNullException("password");
var securePassword = new SecureString();
foreach (char c in password)
securePassword.AppendChar(c);
securePassword.MakeReadOnly();
return securePassword;
}
Đây là một mẹo linq giá rẻ.
SecureString sec = new SecureString();
string pwd = "abc123"; /* Not Secure! */
pwd.ToCharArray().ToList().ForEach(sec.AppendChar);
/* and now : seal the deal */
sec.MakeReadOnly();
Tôi sẽ ném cái này ra khỏi đó. Tại sao?
Bạn không thể thay đổi tất cả các chuỗi của mình thành các chuỗi bảo mật và đột nhiên ứng dụng của bạn "an toàn". Chuỗi bảo mật được thiết kế để giữ cho chuỗi được mã hóa càng lâu càng tốt và chỉ được giải mã trong một khoảng thời gian rất ngắn, xóa sạch bộ nhớ sau khi một thao tác được thực hiện trên nó.
Tôi sẽ nguy hiểm khi nói rằng bạn có thể có một số vấn đề ở cấp thiết kế để giải quyết trước khi lo lắng về việc bảo mật chuỗi ứng dụng của bạn. Cung cấp cho chúng tôi thêm một số thông tin về những gì bạn đang cố gắng làm và chúng tôi có thể giúp đỡ tốt hơn.
không có linq ưa thích, không thêm tất cả các ký tự bằng tay, chỉ đơn giản và đơn giản:
var str = "foo";
var sc = new SecureString();
foreach(char c in str) sc.appendChar(c);
var sc = new SecureString(); foreach(char c in "foo") sc.appendChar(c);
Tôi chỉ muốn chỉ ra cho tất cả mọi người nói, "Đó không phải là vấn đề SecureString
", rằng nhiều người hỏi câu hỏi này có thể nằm trong một ứng dụng, vì lý do nào, có lý do hay không, họ không đặc biệt quan tâm đến việc có một bản sao tạm thời của mật khẩu nằm trên heap dưới dạng chuỗi có khả năng GC, nhưng chúng phải sử dụng API chỉ chấp nhận SecureString
các đối tượng. Vì vậy, bạn có một ứng dụng mà bạn không quan tâmcho dù mật khẩu có ở trên heap hay không, có thể đó chỉ là sử dụng nội bộ và mật khẩu chỉ ở đó vì nó được yêu cầu bởi các giao thức mạng cơ bản và bạn thấy rằng chuỗi đó lưu trữ mật khẩu không thể được sử dụng để thiết lập PowerShell từ xa Runspace - nhưng không có một lớp lót đơn giản, dễ dàng để tạo raSecureString
đó là điều bạn cần. Đó là một sự bất tiện nhỏ - nhưng có lẽ giá trị của nó để đảm bảo rằng các ứng dụng thực sự làm cần SecureString
không điều kiện nhiệt độ các tác giả để sử dụng System.String
hoặc System.Char[]
trung gian. :-)
Nếu bạn muốn nén chuyển đổi từ a string
thành a SecureString
thành một LINQ
câu lệnh, bạn có thể diễn đạt nó như sau:
var plain = "The quick brown fox jumps over the lazy dog";
var secure = plain
.ToCharArray()
.Aggregate( new SecureString()
, (s, c) => { s.AppendChar(c); return s; }
, (s) => { s.MakeReadOnly(); return s; }
);
Tuy nhiên, hãy nhớ rằng việc sử dụng LINQ
không cải thiện tính bảo mật của giải pháp này. Nó bị lỗ hổng giống như bất kỳ chuyển đổi từ string
sang SecureString
. Miễn là bản gốc string
vẫn còn trong bộ nhớ, dữ liệu dễ bị tổn thương.
Điều đó đang được nói, những gì tuyên bố trên có thể cung cấp là kết hợp việc tạo ra SecureString
, khởi tạo của nó với dữ liệu và cuối cùng khóa nó khỏi sửa đổi.
2 phần mở rộng sau đây nên thực hiện thủ thuật:
Đối với một char
mảng
public static SecureString ToSecureString(this char[] _self)
{
SecureString knox = new SecureString();
foreach (char c in _self)
{
knox.AppendChar(c);
}
return knox;
}
Va cho string
public static SecureString ToSecureString(this string _self)
{
SecureString knox = new SecureString();
char[] chars = _self.ToCharArray();
foreach (char c in chars)
{
knox.AppendChar(c);
}
return knox;
}
Cảm ơn John Dagg cho lời AppendChar
giới thiệu.
bạn có thể sử dụng tập lệnh đơn giản này
private SecureString SecureStringConverter(string pass)
{
SecureString ret = new SecureString();
foreach (char chr in pass.ToCharArray())
ret.AppendChar(chr);
return ret;
}
12345
... đó là thứ mà một thằng ngốc có trong hành lý của mình!"