Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/370.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在不使用字符串的情况下将密码从java发送到postgresql?_Java_Postgresql_Passwords_Password Protection - Fatal编程技术网

如何在不使用字符串的情况下将密码从java发送到postgresql?

如何在不使用字符串的情况下将密码从java发送到postgresql?,java,postgresql,passwords,password-protection,Java,Postgresql,Passwords,Password Protection,我知道当涉及到密码时,char[]比String更可取,因为String是不可变的。但我还没有弄明白如何把它传递给一份事先准备好的声明。考虑这个代码: Connection con = MyDBManager.connect(); PreparedStatement stm = con.prepareStatement( "INSERT INTO my_table(username, password) VALUES(? ?)"); String username =

我知道当涉及到密码时,char[]比String更可取,因为String是不可变的。但我还没有弄明白如何把它传递给一份事先准备好的声明。考虑这个代码:

Connection con = MyDBManager.connect();
PreparedStatement stm = con.prepareStatement(
    "INSERT INTO my_table(username, password) VALUES(? ?)");
String username = "Jonny";
stm.setString(username);
char[] password = new char[] {'a','b','c','d'};
stm.SetString(password.toString());
它可以工作,但我怀疑调用password.toString会破坏使用char[]的全部目的,所以我应该怎么做

是的,我知道密码不应该以明文形式存储。密码是散列的,但我仍然希望使用char[]的优点

这似乎是可行的,我还将数据库中的字段从text改为bytea,我认为理论上应该提供与char[]相同的好处,但我强烈感觉我做得不对:

byte[] password = new byte[] {'a','b','c','d'};
stm.SetBytes(password);
也许我的方法完全错了,但我的要求是密码散列不应该存在于不可变对象中。除了PreparedStatement之外,我还可以通过其他方式将其发送到数据库

对评论的答复: 我从@rzwitserroot的回答中学到了很多东西,但不幸的是,这没有帮助。从不在不可变对象中使用密码哈希是一项不可协商的要求。

为什么密码是char[]形式? 我知道当涉及到密码时,char[]比String更可取,因为String是不可变的

如果你的意思是:那么现在你不能更改密码了。那是不对的

也许你指的是你不能把它们擦干净,但万一你不能,让我解释一下:

char[]比String更可取的原因只有一个,这是非常可疑的:使用char[],可以“擦除”数组。也就是说,一旦您的进程java代码不再需要密码,您就可以显式运行Arrays.fillthePassword,char 0;现在RAM不再包含密码。你不能用字符串来做这件事——你可以清空你的引用,但那只是“抹去了藏宝图”。这不是挖出宝藏然后把宝藏砸成碎片。愿意挖掘整个海滩的人仍然会找到它

这听起来很棒,这是解释为什么一大堆基于密码的API使用char[]而不是String的唯一原因。然而,作为一项原则,这是非常可疑的,你绝对不应该依赖它:

如果您不信任的其他进程可以访问您的进程的内存,那么您已经被完全淹没了。你应该从源头上解决这个问题,而不是试图通过减少暴露来缓解这个问题。这就好比在你的动脉上有一个巨大的裂口,并通过连接一个持续供应的血袋来修复它,以对抗症状,而不是用绷带包扎伤口来封闭真正的裂口。如果这个洞不知何故无法关闭,我想对抗症状总比什么都没有好,但这是一个糟糕的选择。 在操作系统和CPU缓存之间,你无法保证清除你的字符数组意味着密码在硬件的任何部分都不是黑客可以找到的。 无论如何,我不会认为任何在密码中存储字符串的代码是不安全的。事实上,我害怕以char[]形式存储它们的代码-我担心作者会误解它提供的保护,或者他们会直接忘记将其归零:这会让代码的读者做出错误的假设,即密码被删除,这可能不是真的,这意味着,如果有任何东西试图获得内存内容的转储,密码是不可恢复的,这也可能不是真的

NB:在安全方面,养成撰写詹姆斯·邦德电影剧本的习惯是个好主意。这是给你的电影剧本:

您在云托管环境中,在虚拟化PC上运行服务器。该云的运营商搞砸了,一旦删除服务器(实际上只是终止在运行数百台PC的主机上运行的虚拟PC),它们不会擦除进程的内存。有人决定滥用这一点:他们让云主机给他们一台装有linux的PC,然后安装一个简单的应用程序,扫描虚拟PC自己的内存,查找任何看起来像密码的东西并报告,然后关闭机器并终止它,并要求另一台

通过使用char[]并清除密码,您可以更安全地避免此问题。。但如果服务器只是崩溃或死机,则不会发生这种情况,例如Amazon EC2就是这样被使用的。请参阅netflix的混乱猴子文档,整个社区普遍认为这是正确的做法,在这种情况下,有些密码恰好处于char[]阶段,存在风险。更不用说记忆中的所有其他地方了,它们最终都会消失

查看债券级别脚本如何帮助澄清问题?这表明清除字符数组有一定的意义,但这不是万无一失的

如何在postgres中存储密码 散列是一个很好的方法 也不好。至少,这取决于你对“散列”这个词的意思

正确的方法包括两件事:

一个“salt”——问题是,很多人都把i-veyou作为密码。使用什么哈希算法无关紧要,哈希算法本质上是将相同的输入哈希到相同的输出,因此,如果我得到数据库的完整转储,我需要做的就是运行SELECT passhash,COUNT*AS ct FROM accounts GROUP by passhash ORDER by ct DESC LIMIT 1,然后瞧——那个哈希?这就是我给你的,然后我可以从passhash=?,和该列表中的每个人的帐户中选择用户名?我可以用pass I loveYou以他们的身份登录。就这么简单。salt解决了这个问题:其思想是,在创建帐户时为每个帐户生成一个随机数,然后将该随机数存储在数据库中。存储的哈希值是对值进行哈希运算的结果:CONCATENATEsalt,password。现在,每个白痴用户使用iloveyou作为密码的结果都是不同的散列。要检查密码,您需要输入密码,检索salt,重新创建CONCATsalt,传递,散列该密码,并确认它与DB条目匹配

你需要一个既慢又奇怪的散列算法。例如,比特币使用SHA-256,因此有大量的专用机器可以为SHA-256每毫秒生成数十亿个哈希,还有一些专门的硬件,这些硬件你没有,比你拥有的任何计算机都快得多。那很糟糕,你不想让黑客占优势。因此,您需要一个非常慢的哈希算法,并且不容易针对自定义硬件进行优化。BCrypt、SCrypt和PBKDF是这方面常用的变体。它们都很好,BCrypt更老,从这个意义上说“更差”,但也更简单,更可靠。随便选一个

请注意,大多数库都已经处理了整个salt业务,不需要显式生成和存储这些库的API。这些库的API很简单:给我一个东西放在DB中作为这个密码,用户输入了这个密码,这就是您之前告诉我放在DB中的东西。是火柴吗?'要放在DB'中的东西包含salt和哈希结果,并组合成一个字符串

好吧,那我怎么才能得到bcrypt lib给postgres的“放入DB的东西”? 它通过一根电线或至少是一个本地插座,进入postgres WAL日志,然后到处都是。事实上,这个东西也就在数据库中

您可以以某种方式从系统硬件中消除此哈希值的想法是完全不可能的

因此,只需制作一个java.lang.String。没关系。

为什么密码是char[]格式? 我知道当涉及到密码时,char[]比String更可取,因为String是不可变的

如果你的意思是:那么现在你不能更改密码了。那是不对的

也许你指的是你不能把它们擦干净,但万一你不能,让我解释一下:

char[]比String更可取的原因只有一个,这是非常可疑的:使用char[],可以“擦除”数组。也就是说,一旦您的进程java代码不再需要密码,您就可以显式运行Arrays.fillthePassword,char 0;现在RAM不再包含密码。你不能用字符串来做这件事——你可以清空你的引用,但那只是“抹去了藏宝图”。这不是挖出宝藏然后把宝藏砸成碎片。愿意挖掘整个海滩的人仍然会找到它

这听起来很棒,这是解释为什么一大堆基于密码的API使用char[]而不是String的唯一原因。然而,作为一项原则,这是非常可疑的,你绝对不应该依赖它:

如果您不信任的其他进程可以访问您的进程的内存,那么您已经被完全淹没了。你应该从源头上解决这个问题,而不是试图通过减少暴露来缓解这个问题。这就好比在你的动脉上有一个巨大的裂口,并通过连接一个持续供应的血袋来修复它,以对抗症状,而不是用绷带包扎伤口来封闭真正的裂口。如果这个洞不知何故无法关闭,我想对抗症状总比什么都没有好,但这是一个糟糕的选择。 在操作系统和CPU缓存之间,你无法保证清除你的字符数组意味着密码在硬件的任何部分都不是黑客可以找到的。 无论如何,我不会认为任何在密码中存储字符串的代码是不安全的。事实上,我害怕以char[]形式存储它们的代码——我担心作者会误解它提供的保护,或者他们会直接忘记将其归零:这让代码的读者做出错误的假设,即密码被删除,这可能不是真的,这意味着密码不是r 若有任何东西能够获得内存内容的转储,那个么ecoverable可能也是不正确的

NB:在安全方面,养成撰写詹姆斯·邦德电影剧本的习惯是个好主意。这是给你的电影剧本:

您在云托管环境中,在虚拟化PC上运行服务器。该云的运营商搞砸了,一旦删除服务器(实际上只是终止在运行数百台PC的主机上运行的虚拟PC),它们不会擦除进程的内存。有人决定滥用这一点:他们让云主机给他们一台装有linux的PC,然后安装一个简单的应用程序,扫描虚拟PC自己的内存,查找任何看起来像密码的东西并报告,然后关闭机器并终止它,并要求另一台

通过使用char[]并清除密码,您可以更安全地避免此问题。。但如果服务器只是崩溃或死机,则不会发生这种情况,例如Amazon EC2就是这样被使用的。请参阅netflix的混乱猴子文档,整个社区普遍认为这是正确的做法,在这种情况下,有些密码恰好处于char[]阶段,存在风险。更不用说记忆中的所有其他地方了,它们最终都会消失

查看债券级别脚本如何帮助澄清问题?这表明清除字符数组有一定的意义,但这不是万无一失的

如何在postgres中存储密码 散列也没有好处。至少,这取决于你对“散列”这个词的意思

正确的方法包括两件事:

一个“salt”——问题是,很多人都把i-veyou作为密码。使用什么哈希算法无关紧要,哈希算法本质上是将相同的输入哈希到相同的输出,因此,如果我得到数据库的完整转储,我需要做的就是运行SELECT passhash,COUNT*AS ct FROM accounts GROUP by passhash ORDER by ct DESC LIMIT 1,然后瞧——那个哈希?这就是我给你的,然后我可以从passhash=?,和该列表中的每个人的帐户中选择用户名?我可以用pass I loveYou以他们的身份登录。就这么简单。salt解决了这个问题:其思想是,在创建帐户时为每个帐户生成一个随机数,然后将该随机数存储在数据库中。存储的哈希值是对值进行哈希运算的结果:CONCATENATEsalt,password。现在,每个白痴用户使用iloveyou作为密码的结果都是不同的散列。要检查密码,您需要输入密码,检索salt,重新创建CONCATsalt,传递,散列该密码,并确认它与DB条目匹配

你需要一个既慢又奇怪的散列算法。例如,比特币使用SHA-256,因此有大量的专用机器可以为SHA-256每毫秒生成数十亿个哈希,还有一些专门的硬件,这些硬件你没有,比你拥有的任何计算机都快得多。那很糟糕,你不想让黑客占优势。因此,您需要一个非常慢的哈希算法,并且不容易针对自定义硬件进行优化。BCrypt、SCrypt和PBKDF是这方面常用的变体。它们都很好,BCrypt更老,从这个意义上说“更差”,但也更简单,更可靠。随便选一个

请注意,大多数库都已经处理了整个salt业务,不需要显式生成和存储这些库的API。这些库的API很简单:给我一个东西放在DB中作为这个密码,用户输入了这个密码,这就是您之前告诉我放在DB中的东西。是火柴吗?'要放在DB'中的东西包含salt和哈希结果,并组合成一个字符串

好吧,那我怎么才能得到bcrypt lib给postgres的“放入DB的东西”? 它通过一根电线或至少是一个本地插座,进入postgres WAL日志,然后到处都是。事实上,这个东西也就在数据库中

您可以以某种方式从系统硬件中消除此哈希值的想法是完全不可能的


因此,只需制作一个java.lang.String。很好。

@Kayaman不,我没有。我服从命令我怀疑你在这里打一场败仗。谁知道JVM中的密码数据会发生什么变化?还是数据库驱动程序?在这样的情况下使用字符串是一件相对较新的事情,JVM的许多部分都是旧的。@Kayaman好吧,只是一个非常真实的情况是,作为程序员,我必须遵守荒谬的要求,而代码将由经验丰富的程序员审查,他们也认为这是一个荒谬的要求,但是,他们不会仅仅因为你的代码不符合规范就批准你的代码,他们也没有理由对你“友好”,因为如果他们这样做了,他们会触犯法律。@Kayaman该要求是不可谈判的。就是这样。ps.setCharacterStream2,新的CharacterRead
埃尔哈什;向你的孩子们问好。@Kayaman不,我不是。我服从命令我怀疑你在这里打一场败仗。谁知道JVM中的密码数据会发生什么变化?还是数据库驱动程序?在这样的情况下使用字符串是一件相对较新的事情,JVM的许多部分都是旧的。@Kayaman好吧,只是一个非常真实的情况是,作为程序员,我必须遵守荒谬的要求,而代码将由经验丰富的程序员审查,他们也认为这是一个荒谬的要求,但是,他们不会仅仅因为你的代码不符合规范就批准你的代码,他们也没有理由对你“友好”,因为如果他们这样做了,他们会触犯法律。@Kayaman该要求是不可谈判的。就是这样。ps.setCharacterStream2,新characterreaderhash;向你的孩子问好。评论不是为了进行长时间的讨论;此对话已结束。评论不用于扩展讨论;这段对话已经结束。