Java中如何对字符串进行加密

2024-01-23

我需要的是加密将显示在二维条形码(PDF-417)中的字符串,这样当有人想扫描它时,它就不会可读。

其他需求:

  • 不应该很复杂
  • 它不应该由 RSA、PKI 基础设施、密钥对等组成。

它必须足够简单,以消除人们的窥探,并且对于有兴趣获取该数据的其他公司来说必须易于解密。他们打电话给我们,我们告诉他们标准或给他们一些简单的密钥,然后可以用于解密。

也许这些公司可以使用不同的技术,因此最好坚持一些不依赖于某些特殊平台或技术的标准。

你有什么建议?有没有一些Java类在做encrypt() & decrypt()实现高安全标准没有太多复杂性?


这是通过 Google 和安全显示的第一页 所有实现中的漏洞让我感到畏缩,所以我 发布此内容是为了添加有关其他人加密的信息,因为它 已经7 Years从原来的帖子。我持有一个硕士在 计算机工程并花了很多时间学习和学习 密码学,所以我投入我的两分钱让互联网成为 更安全的地方。

另外,请注意,对于给定的情况,许多实现可能是安全的 情况,但为什么要使用这些并可能意外地做出一个 错误?使用可用的最强大的工具,除非您有 具体原因不去。总的来说,我强烈建议使用图书馆和 如果可以的话,远离细节。

2018 年 4 月 5 日更新:我重写了一些部分,使它们更容易理解,并更改了推荐的库Jasypt http://www.jasypt.org/ to Google 的新库 Tink https://github.com/google/tink/,我建议完全删除Jasypt http://www.jasypt.org/从现有的设置。

Foreword

我将在下面概述安全对称加密的基础知识,并指出当人们使用标准 Java 库自己实现加密时我在网上看到的常见错误。如果您想跳过所有细节,请运行至Google 的新库 Tink https://github.com/google/tink/将其导入您的项目并使用 AES-GCM 模式进行所有加密,您将是安全的。

现在,如果您想了解有关如何在 Java 中加密的具体细节,请继续阅读:)

分组密码

首先,您需要选择一个对称密钥分组密码。分组密码是一种用于创建伪随机性的计算机功能/程序。伪随机性是假随机性,除了量子计算机之外,没有任何计算机能够区分它和真正的随机性。分组密码就像密码学的构建块,当与不同的模式或方案一起使用时,我们可以创建加密。

现在关于当今可用的分组密码算法,请确保NEVER, 我重复NEVER use DES http://en.wikipedia.org/wiki/Data_Encryption_Standard,我什至会说永远不要使用3DES http://en.wikipedia.org/wiki/3DES。甚至斯诺登的美国国家安全局发布的版本也能够验证真正尽可能接近伪随机的唯一分组密码是AES 256 http://en.wikipedia.org/wiki/Advanced_Encryption_Standard。还有 AES 128;区别在于 AES 256 在 256 位块中工作,而 AES 128 在 128 位块中工作。总而言之,尽管已发现一些弱点,但 AES 128 仍被认为是安全的,但 256 却非常可靠。

有趣的事实DES http://en.wikipedia.org/wiki/Data_Encryption_Standard早在国家安全局成立之初就被美国国家安全局打破,并实际上保守了几年的秘密。尽管有些人仍然声称3DES http://en.wikipedia.org/wiki/3DES是安全的,有相当多的研究论文发现并分析了其弱点3DES http://en.wikipedia.org/wiki/3DES.

加密模式

当您采用分组密码并使用特定方案时,就会创建加密,以便将随机性与密钥相结合,从而创建只要您知道密钥即可可逆的东西。这称为加密模式。

以下是加密模式和最简单的模式(称为 ECB)的示例,以便您可以直观地了解正在发生的情况:

您在网上最常见的加密模式如下:

欧洲央行 CTR、CBC、GCM

除了列出的模式之外,还存在其他模式,研究人员一直致力于寻找新模式来改善现有问题。

Now let's move on to implementations and what is secure. NEVER use ECB this is bad at hiding repeating data as shown by the famous Linux penguin https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation.Linux Penguin Example

在Java中实现时,请注意,如果使用以下代码,则默认设置ECB模式:

Cipher cipher = Cipher.getInstance("AES");

...危险这是一个漏洞!不幸的是,这种情况在 StackOverflow 和在线教程和示例中随处可见。

随机数和 IV

为了响应欧洲央行模式中发现的问题,创建了也称为 IV 的公告。我们的想法是,我们生成一个新的随机变量并将其附加到每个加密中,这样当您加密两条相同的消息时,它们就会不同。这背后的美妙之处在于 IV 或随机数是公共知识。这意味着攻击者可以访问此内容,但只要他们没有您的密钥,他们就无法利用这些知识做任何事情。

我会看到的常见问题是人们会将 IV 设置为静态值,就像代码中的固定值一样。这就是 IV 的陷阱,当您重复一次时,您实际上会危及整个加密的安全性。

生成随机 IV

SecureRandom randomSecureRandom = new SecureRandom();
byte[] iv = new byte[cipher.getBlockSize()];
randomSecureRandom.nextBytes(iv);
IvParameterSpec ivParams = new IvParameterSpec(iv);

Note:SHA1 已损坏,但我找不到如何在这个用例中正确实现 SHA256,所以如果有人想破解这个并更新它那就太棒了!此外,SHA1 攻击仍然是非常规的,因为在一个巨大的集群上可能需要几年的时间才能破解。在这里查看详细信息。 https://shattered.io/

点击率实施

CTR 模式不需要填充。

 Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");

CBC实施

如果您选择实现 CBC 模式,请使用 PKCS7Padding 执行以下操作:

 Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");

CBC 和 CTR 漏洞以及为什么应该使用 GCM

尽管 CBC 和 CTR 等其他一些模式是安全的,但它们会遇到攻击者可以翻转加密数据、在解密时更改其值的问题。假设您加密了一条假想的银行消息“Sell 100”,您的加密消息看起来像“eu23ng”,攻击者将一位更改为“eu53ng”,当解密您的消息时,它突然变成“Sell 900”。

为了避免这种情况,大多数互联网都使用 GCM,每次您看到 HTTPS 时,他们可能都在使用 GCM。 GCM 使用哈希对加密消息进行签名,并检查以验证消息是否未使用此签名进行更改。

由于 GCM 的复杂性,我会避免实施它。你最好使用谷歌的新库 Tink https://github.com/google/tink/因为如果你不小心重复 IV,你就会泄露 GCM 箱中的密钥,这是最终的安全缺陷。新的研究人员正在致力于开发 IV 重复抵抗加密模式,即使您重复 IV,密钥也不会处于危险之中,但这尚未成为主流。

现在,如果您确实想实现 GCM,这里有一个链接到一个很好的 GCM 实现 https://gist.github.com/praseodym/f2499b3e14d872fe5b4a。但是,我无法确保安全性或是否正确实施,但它奠定了基础。另请注意,GCM 中没有填充。

Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");

密钥与密码

另一个非常重要的注意事项是,当涉及到密码学时,密钥和密码不是同一件事。密码学中的密钥需要具有一定量的熵和随机性才能被认为是安全的。这就是为什么您需要确保使用正确的加密库来为您生成密钥。

因此,您实际上可以在这里执行两种实现,第一个是使用在这个 StackOverflow 线程用于随机密钥生成 https://stackoverflow.com/questions/18228579/how-to-create-a-secure-random-aes-key-in-java。此解决方案使用安全随机数生成器从头开始创建可供您使用的密钥。

另一个不太安全的选项是使用用户输入,例如密码。我们讨论的问题是密码没有足够的熵,所以我们必须使用PBKDF2 https://en.wikipedia.org/wiki/PBKDF2,一种获取密码并对其进行强化的算法。这里有一个我喜欢的 StackOverflow 实现 https://stackoverflow.com/a/27928435/2607972。然而,Google Tink 库内置了所有这些功能,您应该利用它。

安卓开发者

这里需要指出的重要一点是,你的 android 代码是可逆向工程的,大多数情况下大多数 java 代码也是如此。这意味着如果您在代码中以纯文本形式存储密码。黑客可以轻松检索它。通常,对于这些类型的加密,您需要使用非对称加密等。这超出了本文的范围,因此我将避免深入探讨。

An 2013年有趣的读物 https://cs.ucsb.edu/%7Echris/research/doc/ccs13_cryptolint.pdf:指出 Android 中 88% 的加密实现做得不正确。

最后的想法

我再次建议避免直接实现用于加密的 java 库并使用谷歌天克 https://github.com/google/tink/,这将为您省去麻烦,因为他们在正确实现所有算法方面确实做得很好。即使这样,也要确保检查 Tink github 上提出的问题、到处弹出的漏洞。

如果您有任何问题或反馈,请随时发表评论! 安全性总是在变化,您需要尽力跟上它:)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java中如何对字符串进行加密 的相关文章

随机推荐

  • addslashes() 可以安全地防止 HTML 属性中的 XSS 吗?

    我不得不开发一个以前的开发人员留下的旧网络应用程序 它使用addslashes 来防止HTML属性上的XSS 这是一个例子 这是否容易受到 XSS 攻击 有没有什么方法可以让 javascript 在 value 属性中运行 就像在 src
  • 未定义的方法“分页”

    我正在尝试使用 will paginate gem 但出了点问题 我被困住了undefined method paginate 错误 我读了很多问题并尝试了很多事情 这是我所得到的 这是我的 LocationsController rb d
  • 在 pytube 中显示进度

    import pytube def video downloader vid url str input Enter Video URL print Connecting Please wait video pytube YouTube v
  • 在 ASP.NET 中处理数据时如何更新进度消息?

    我有一个流程 它输出逐步消息 即 处理项目 1 项目 2 中的错误等 我希望在整个过程中 而不是最后 将其输出给用户 我很确定我需要使用线程来完成此操作 但找不到合适的示例 这不是线程问题 而是 Web 浏览器 UI 问题 您希望浏览器在您
  • 如何仅对我想要提交的文件运行 Prettier?

    Using Husky https github com typicode husky 我已经设置了我的package json使用预提交挂钩 以便我的 JavaScript 代码使用以下格式进行格式化Prettier https pret
  • 具有模板参数大小的 const char 数组与 char 指针

    今天我在一些代码中看到了以下类型的构造 template
  • std::forward 与 std::move 的用法[重复]

    这个问题在这里已经有答案了 我总是读到std forward仅适用于模板参数 然而 我问自己为什么 请参见以下示例 void ImageView setImage const Image image image image void Ima
  • 在 React Native 中使用 Firebase 进行 Google 登录

    请注意 由于需要解释 问题可能会很长 否则它可能会非常模糊并导致相同的旧答案 我在创建时遇到问题Google Sign In页面进入React Native using firebase 基于firebase文档 随着 3 1 0 SDK
  • 如何防止 Windows(手机)8.1 通用应用程序锁屏?

    有谁知道如何防止 Windows 手机 8 1 通用应用程序中的锁屏 在 Windows Phone 8 中 我使用过 PhoneApplicationService Current UserIdleDetectionMode IdleDe
  • 将 C++ int 数组编组为 C#

    我想将一个整数数组从 C 编组到 C 我有一个非托管 C dll 其中包含 DLL EXPORT int fnwrapper intarr int test new int 3 test 0 1 test 1 2 test 2 3 retu
  • 使用 GitLab 将 Node.js 应用程序持续部署到 Heroku

    有涵盖 Ruby 和 Python 应用程序部署的教程 但我找不到 NodeJS 的良好文档或示例 http docs gitlab com ce ci examples test and deploy python application
  • 如何在 C++ 中清除 2D 矢量

    任何人都可以建议我 如何在 C 中清除 2D 矢量 我必须编写需要读取 Matrix Process 和 Clear Matrix 的程序 并为下一次读取操作做好准备 我已经使用向量创建了二维数组 gt 我正在填充但无法重置 下面是参考代码
  • WPF - 为基类实现 System.ComponentModel.INotifyPropertyChanged

    我想为基类上的属性实现 System ComponentModel INotifyPropertyChanged 接口 但我不太确定如何连接它 以下是我想要接收通知的属性的签名 public abstract bool HasChanged
  • 可编辑的 WPF 列表视图

    我想做一个ListView当用户双击某个项目时可编辑 我意识到网络上有很多示例 但是这些示例都是基于IsSelected属性 而不是处理双击事件 有什么想法或指示吗 UPDATE 因此 我遇到的另一个问题是 如何访问数据模板中的控件List
  • 使用假 mongoDB 进行 pytest 测试

    我有连接到 MongoDB 客户端的代码 我正在尝试测试它 为了进行测试 我不想连接到实际的客户端 因此我试图找出一个假客户端来进行测试 代码的基本流程是我在某处有一个函数创建一个pymongo客户端 然后查询并创建一个在其他地方使用的字典
  • 发布 Android 应用程序后,谷歌地图不显示?

    朋友们 在使用模拟器在 Eclipse 上测试应用程序时 谷歌地图可以正确显示 但是当我导出应用程序来发布它时 谷歌地图不见了 谁能指导我我犯了什么错误 任何帮助 将不胜感激 当您导出应用程序以发布它时 您可能不再使用调试密钥库 而是使用自
  • UIBezierPath 未绘制平滑曲线

    我正在使用 UIBezierPath 进行绘图 并且我已经编写了关于触摸事件的代码并且其工作正常 但是我的曲线不平滑 当我移动手指并绘制一些曲线时 它们不平滑 void drawRect CGRect rect UIColor redCol
  • npm WARN 已弃用 [email protected]:core-js@<3 不再维护,由于问题数量较多,不建议使用

    我在创建新的 Angular 应用程序时遇到以下错误 npm 警告已弃用 电子邮件受保护 cdn cgi l email protection core js 我尝试了下面链接中给出的解决方案 但它对我不起作用 错误 请将您的依赖项升级到
  • 查找未注册任何课程的学生姓名 - 学生、教师、课程、课程、已注册

    根据下面的数据库 使用关系代数投影出未注册课程的学生的姓名 Students snum sname major standing age gpa Faculty fid fname deptid Courses cnum cname cou
  • Java中如何对字符串进行加密

    我需要的是加密将显示在二维条形码 PDF 417 中的字符串 这样当有人想扫描它时 它就不会可读 其他需求 不应该很复杂 它不应该由 RSA PKI 基础设施 密钥对等组成 它必须足够简单 以消除人们的窥探 并且对于有兴趣获取该数据的其他公