代码之家  ›  专栏  ›  技术社区  ›  RLH

如何正确地从SecureString发出二进制数据,以便稍后可以将其转换为字符串?

  •  0
  • RLH  · 技术社区  · 8 年前

    我需要从用户那里收集一串敏感信息。我正在使用WPF PasswordBox 请求此信息。对于新手来说 密码箱 控件提供了 SecurePassword 作为 SecureString 对象而不是不安全的 string 对象在我的应用程序中,来自 密码箱 作为 SecureString 加密方法。

    我需要能够做的是将数据封送到一个字节数组,该数组本质上表示一个。网 值,而不首先将数据转换为。网 一串 . 更具体地说,假设 SecureString 值为。。。

    wen jian efghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz1234567890 ` ~!@#$%^&*()_-+={[}]|:;“'<,>/ ≈篭母

    ...如何将其转换为等效于的字节数组。Net字符串,该字符串已序列化并写入具有 StreamWriter ?

    通过使用 Marshal.SecureStringToCoTaskMemUnicode(...) 我可以用更传统的西方文本来实现这一点。然而,当我使用额外的非典型字符和日语文本字符串(见最后几个粗体字符)创建上述文本字符串时,我获得分配给 IntPtr 这个位置似乎不再正常工作了。

    如何发出 SecureString 以安全的方式,使返回的字节数据的结构与标准的字节数据相同。Net字符串,序列化为二进制输出?

    注释

    请暂时忽略所有安全问题。我正在对我的应用程序进行各种安全升级。现在,我需要使用 SecureString 用于将敏感数据传输到加密机。解密程序(目前)仍需要将此数据解密到 一串 值,这就是为什么我需要了解如何序列化 SecureString 转换为与的二进制格式类似的二进制格式 一串 对象

    我同意这种方法有点不幸,但是,我必须对现有应用程序进行增量改进,第一阶段是锁定中的数据 SecureString 从用户到加密程序的对象。

    1 回复  |  直到 8 年前
        1
  •  1
  •   Evk    8 年前

    如果需要将安全字符串写入流,我建议创建如下方法:

    public static class Extensions {
        public static void WriteSecure(this StreamWriter writer, SecureString sec) {
            int length = sec.Length;
            if (length == 0)
                return;
            IntPtr ptr = Marshal.SecureStringToBSTR(sec);
            try {
                // each char in that string is 2 bytes, not one (it's UTF-16 string)
                for (int i = 0; i < length * 2; i += 2) {
                    // so use ReadInt16 and convert resulting "short" to char
                    var ch = Convert.ToChar(Marshal.ReadInt16(ptr + i));
                    // write
                    writer.Write(ch);
                }
            }
            finally {
                // don't forget to zero memory
                Marshal.ZeroFreeBSTR(ptr);
            }
        }
    }
    

    如果确实需要字节数组,也可以重用此方法:

    byte[] result;
    using (var ms = new MemoryStream()) {
        using (var writer = new StreamWriter(ms)) {
            writer.WriteSecure(secureString);
        }
        result = ms.ToArray();
    }
    

    虽然第一条评论中的方法可能有点夸张(不确定这对你们是否重要)。

    推荐文章