当前位置: 首页 > news >正文

电子商务网站建设流程关键词整站优化

电子商务网站建设流程,关键词整站优化,网站怎么做下载功能,网站开发答辩设计预期目标抽象 在2017年#xff0c;我撰写了一个由三部分组成的系列文章#xff0c;内容涉及选择最佳的哈希和加密算法。 在对该系列进行研究时#xff0c;我学到了很多有关哈希和加密的知识。 我学到的最重要的事情是#xff0c;尽管我必须对如何使用最安全的算法进行自我教育… 抽象 在2017年我撰写了一个由三部分组成的系列文章内容涉及选择最佳的哈希和加密算法。 在对该系列进行研究时我学到了很多有关哈希和加密的知识。 我学到的最重要的事情是尽管我必须对如何使用最安全的算法进行自我教育但我也必须将这些算法的开发工作留给专家。 话虽如此我开始考虑Java与加密专家特别是OpenSSL的互操作性。 我的第3部分系列仅从Java的角度着眼于加密。 我想知道Java与OpenSSL之类的工具进行互操作将有多么困难。 本博客的目的是演示Java与OpenSSL的互操作性 使用OpenSSL生成私钥和公钥 使用OpenSSL加密值 用Java解密值 免责声明 这篇文章仅供参考。 在使用所提供的任何信息之前请认真思考。 从中学到东西但最终自己做出决定风险自负。 要求 我使用以下主要技术完成了本文的所有工作。 您可能可以使用不同的技术或版本来做相同的事情但不能保证。 OpenJDK运行时环境Zulu11.39 15-CA内部版本11.0.7 10-LTS OpenSSL 1.1.1c 2019年5月28日 Apache NetBeans IDE 11.3 Maven 3.3.9与NetBeans捆绑在一起 dependenciesdependencygroupIdorg.junit.jupiter/groupIdartifactIdjunit-jupiter-api/artifactIdversion5.5.2/versionscopetest/scope/dependencydependencygroupIdorg.junit.jupiter/groupIdartifactIdjunit-jupiter-params/artifactIdversion5.5.2/versionscopetest/scope/dependencydependencygroupIdorg.junit.jupiter/groupIdartifactIdjunit-jupiter-engine/artifactIdversion5.5.2/versionscopetest/scope/dependency /dependenciespluginManagementpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-clean-plugin/artifactIdversion2.5/version/pluginplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-resources-plugin/artifactIdversion2.6/version/pluginplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdversion3.8.1/versionconfigurationdebugtrue/debug/configuration/pluginplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-surefire-plugin/artifactIdversion3.0.0-M4/versionconfigurationargLine-Dfile.encodingUTF8/argLine/configuration/pluginplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-jar-plugin/artifactIdversion2.4/version/pluginplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-install-plugin/artifactIdversion2.4/version/plugin/plugins /pluginManagement下载 访问我的GitHub页面https://github.com/mjremijan以查看我所有的开源项目。 这篇文章的代码位于 https : //github.com/mjremijan/thoth-rsa 背景 当我使用Microservices将Monolith应用程序模块化时我开始怀疑是否能够互操作OpenSSL和Java。 使用微服务时应用程序仍然需要加密和解密敏感的配置数据例如数据库密码但是微服务使用的小型运行时环境给这带来了挑战。 借助Monolith架构Java / Jakarta EE应用程序服务器可以处理应用程序的加密和解密。 诸如数据库连接池之类的托管资源是在EE应用程序服务器中配置的其他其他加密值通常可以存储在JNDI中。 在这两种情况下服务器都提供加密和解密功能而应用程序不知道任何细节。 应用服务器可以为应用提供托管资源或解密值。 但是在微服务架构中运行时例如Spring Boot保持“较小”状态并且不提供与EE应用程序服务器一样多的功能。 数据库连接就是一个很好的例子。 在Spring Boot中配置数据库连接很容易但是您如何支持密码加密和解密 现在它必须得到DevOps和开发团队的支持。 注意其他微服务技术例如Kubernetes正在努力填补空白并提供类似于EE应用程序服务器的加密功能。 所以这让我开始思考。 DevOps生活在Linux / Unix世界中。 开发人员生活在Java世界中。 为什么不将两个世界放在一起以支持加密/解密策略 这将使DevOps和开发人员能够尽自己所能。 为此我首先需要明确定义目标。 目标 从Monolith架构迁移到微服务很慢。 是的存在用于加密和解密的微服务基础结构解决方案。 但是如果该基础结构不可用则在3-5年的过渡期内不会为您提供帮助。 为了支持过渡我决定了以下目标。 选择的加密工具是OpenSSL。 它在每个Linux / Unix系统上都是行业标准并且对于所有DevOps团队都是熟悉的。 由DevOps或其他团队执行的加密因此职责分离。 开发团队中没有人会知道未加密的价值。 所有环境都将使用自己的密钥。 没有密钥共享。 可以随时重新生成所有密钥和加密值而无需更改应用程序。 加密将是整个文件或属性文件中的特定值。 使用DevOps和开发团队共同商定并实施的策略加密的值和密钥可用于Java运行时。 Java应用程序出于其所需的任何目的执行解密。 不要记录加密值 牢记这些目标让我们开始一段旅程。 使用哪种算法 我需要回答的第一个问题是要使用哪种加密算法。 对于加密我可以选择单密钥对称加密还是公共/私有密钥非对称加密。 我的选择是 RSA-4096公钥/私钥非对称加密 选择非对称加密算法的原因是因为公钥/私钥允许最大程度的责任分离。 可能会有独立的团队来生成密钥加密值以及将所有内容放在一起以供运行时使用。 实际上这可以全部由一个团队甚至一个人完成但是非对称加密算法可以灵活地分离这些问题。 至于使用RSA-4096算法根据我的研究它是当今最好最安全的Remijan2017。 现在我们知道要使用哪种算法。 接下来我们将研究生成私钥。 OpenSSL生成私钥 在Java中 PKCS8EncodedKeySpec类期望使用PKCS8编码的RSA私钥。 Java代码nd。 我发现了使用OpenSSL的两种方法。 清单2.1 –用2个命令生成私钥 # Generate key with pkcs1 encoding # Generate private openssl genrsa -out private_key_rsa_4096_pkcs1.pem 4096 # Convert private # Convert key to pkcs8 encoding openssl pkcs8 -topk8 -in private_key_rsa_4096_pkcs1.pem -inform pem -out private_key_rsa_4096_pkcs8-exported.pem -outform pem -nocrypt 在清单2.1中2017年斯坦斯坦私钥是通过2条命令生成的。 第一条命令使用PKCS1编码生成密钥。 第二条命令将PKCS1编码的密钥转换为PKCS8编码的密钥。 清单2.2 –用1个命令生成私钥 # Generate key with pkcs8 encoding # Generate private openssl genpkey -out private_key_rsa_4096_pkcs8-generated.pem -algorithm RSA -pkeyopt rsa_keygen_bits: 4096 在清单2.2中私钥是使用单个命令生成的。 这将产生带有PKCS8编码的密钥。 无需其他转换。 无论您使用清单2.1还是2.2生成私钥生成时的私钥都将如下所示。 -----BEGIN PRIVATE KEY----- MIIJQgIBADANBgkqhkiG9w0BAQEFAASCCSwwggkoAgEAAoICAQDVgLrCSDC5mLRL JYokYX5MOMGibvtRQ9qIQ90d3BO1gAao6ZsbPEFxnOTR9Q3bGsEE5oRlh/FSYS . . kvCjd0ineNZ6OgPVJ/mhPULsZb11noSUPmFqvClb8SQ0BipbKIcSTIJlQt1ZRZ2 INdXsP5kNlRK181jtU/xtQYfwSjkKA -----END PRIVATE KEY----- 大 私钥已生成 现在让我们继续生成公共密钥。 OpenSSL生成公钥 在Java中 X509EncodedKeySpec类期望使用X509编码的RSA公钥。 Java代码nd。 公钥是从私钥生成的因此您必须首先拥有私钥。 清单3.1 –生成公钥 # Export public key in pkcs8 format openssl rsa -pubout -outform pem -in private_key_rsa_4096_pkcs8-generated.pem -out public_key_rsa_4096_pkcs8-exported.pem 清单3.1显示了使用私钥private_key_rsa_4096_pkcs8-generated.pem生成公用密钥public_key_rsa_4096_pkcs8-exported.pem 。 公钥将如下所示。 -----BEGIN PUBLIC KEY----- MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1YC6wkgwuZi0SyWPqJGF TDjBovm77UUPaiEPdHdwTtYAGqOmbGzxBcZzk0fUN2xrBBOaEZYfxUmEkOFzPbF . . oNta8CSsVrqgFW/tI6MQwrQFEOcBPCbh6Pr7NbiuR2LrfoJhUJlD5ofz5eM0419 JSS0RvKh0dF3ddlOKV/TQUsCAwEAAQ -----END PUBLIC KEY----- 大 我们同时拥有私钥和公钥并且都是由OpenSSL生成的。 接下来我们需要Java才能使用这些密钥文件。 这样做我们需要创建KeyFactory PrivateKey和PublicKey对象的实例。 让我们深入一些Java代码 Java KeyFactoryPrivateKeyPublicKey 在使用OpenSSL生成私钥和公钥文件之后是时候编写一些Java代码了。 清单4.1是我完整的Rsa4096类。 我将在下面详细讨论每种方法。 清单4.1 – Rsa4096类 package org.thoth.rsa; import java.io.InputStream; import java.security.KeyFactory; import java.security.PrivateKey; import java.security.PublicKey; import java.security.spec.KeySpec; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.Base64; import javax.crypto.Cipher; /** * * author Michael Remijan mjremijanyahoo.com mjremijan */ public class Rsa4096 { private KeyFactory keyFactory; private PrivateKey privateKey; private PublicKey publicKey; public Rsa4096( String privateKeyClassPathResource , String publicKeyClassPathResource ) throws Exception { setKeyFactory(); setPrivateKey(privateKeyClassPathResource); setPublicKey(publicKeyClassPathResource); } protected void setKeyFactory() throws Exception { this .keyFactory KeyFactory.getInstance( RSA ); } protected void setPrivateKey(String classpathResource) throws Exception { InputStream is this .getClass() .getClassLoader() .getResourceAsStream(classpathResource); String stringBefore new String(is.readAllBytes()); is.close(); String stringAfter stringBefore .replaceAll( \\n , ) .replaceAll( -----BEGIN PRIVATE KEY----- , ) .replaceAll( -----END PRIVATE KEY----- , ) .trim(); byte [] decoded Base64 .getDecoder() .decode(stringAfter); KeySpec keySpec new PKCS8EncodedKeySpec(decoded); privateKey keyFactory.generatePrivate(keySpec); } protected void setPublicKey(String classpathResource) throws Exception { InputStream is this .getClass() .getClassLoader() .getResourceAsStream(classpathResource); String stringBefore new String(is.readAllBytes()); is.close(); String stringAfter stringBefore .replaceAll( \\n , ) .replaceAll( -----BEGIN PUBLIC KEY----- , ) .replaceAll( -----END PUBLIC KEY----- , ) .trim() ; byte [] decoded Base64 .getDecoder() .decode(stringAfter); KeySpec keySpec new X509EncodedKeySpec(decoded); publicKey keyFactory.generatePublic(keySpec); } public String encryptToBase64(String plainText) { String encoded null ; try { Cipher cipher Cipher.getInstance( RSA ); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte [] encrypted cipher.doFinal(plainText.getBytes()); encoded Base64.getEncoder().encodeToString(encrypted); } catch (Exception e) { e.printStackTrace(); } return encoded; } public String decryptFromBase64(String base64EncodedEncryptedBytes) { String plainText null ; try { final Cipher cipher Cipher.getInstance( RSA ); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte [] decoded Base64 .getDecoder() .decode(base64EncodedEncryptedBytes); byte [] decrypted cipher.doFinal(decoded); plainText new String(decrypted); } catch (Exception ex) { ex.printStackTrace(); } return plainText; } } 建设者 public Rsa4096( String privateKeyClassPathResource , String publicKeyClassPathResource ) throws Exception { setKeyFactory(); setPrivateKey(privateKeyClassPathResource); setPublicKey(publicKeyClassPathResource); } 构造函数很简单并带有2个参数。 通过参数名称您可以猜测它们是什么。 第一个参数是OpenSSL生成的私钥文件的完全限定的类路径位置。 第二个参数与公用密钥文件相同。 为什么要将密钥文件放在类路径上 我正在使用Maven运行单元测试来研究此代码。 Maven使在类路径上可用的资源变得容易所以这就是我在这里使用的。 同样这是研究请参阅免责声明 请记住目标之一是使用由DevOps和开发团队商定并实施的策略使密钥可用于Java运行时。 因此您的策略可能有所不同但最终目标却是相同的指向可以读取文件字节的位置。 setKeyFactory protected void setKeyFactory() throws Exception { this .keyFactory KeyFactory.getInstance( RSA ); } setKeyFactory()方法实例化RSA算法的KeyFactory类。 真的很简单 一行代码。 稍后将使用该对象来构建PrivateKey和PublicKey …毕竟这是工厂类:) setPrivateKey protected void setPrivateKey(String classpathResource) throws Exception { InputStream is this .getClass() .getClassLoader() .getResourceAsStream(classpathResource); String stringBefore new String(is.readAllBytes()); String stringAfter stringBefore .replaceAll( \\n , ) .replaceAll( -----BEGIN PRIVATE KEY----- , ) .replaceAll( -----END PRIVATE KEY----- , ) .trim(); byte [] decoded Base64 .getDecoder() .decode(stringAfter); KeySpec keySpec new PKCS8EncodedKeySpec(decoded); privateKey keyFactory.generatePrivate(keySpec); } setPrivateKey()方法实例化PrivateKey 。 在此方法中 ClassLoader用于获取InputStream到类路径上的私钥文件。 文件的字节被读入新的String 。 接下来 String的处理如下 String stringAfter stringBefore .replaceAll( \\n , ) .replaceAll( -----BEGIN PRIVATE KEY----- , ) .replaceAll( -----END PRIVATE KEY----- , ) .trim(); 此处理是必需的因为即使我们使用OpenSSL生成了具有PKCS8编码的私钥文件该文件也无法被Java直接使用。 如果尝试不进行上述处理则会出现以下异常 java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format PKCS8EncodedKeySpec类期望私钥是一行文本其中删除了所有注释Java代码示例…nd。 这就是进行处理的原因。 处理除去换行符和注释后将使用PKCS8EncodedKeySpec和KeyFactory创建PrivateKey 。 KeySpec keySpec new PKCS8EncodedKeySpec(decoded); privateKey keyFactory.generatePrivate(keySpec); setPublicKey protected void setPublicKey(String classpathResource) throws Exception { InputStream is this .getClass() .getClassLoader() .getResourceAsStream(classpathResource); String stringBefore new String(is.readAllBytes()); String stringAfter stringBefore .replaceAll( \\n , ) .replaceAll( -----BEGIN PUBLIC KEY----- , ) .replaceAll( -----END PUBLIC KEY----- , ) .trim(); byte [] decoded Base64 .getDecoder() .decode(stringAfter); KeySpec keySpec new X509EncodedKeySpec(decoded); publicKey keyFactory.generatePublic(keySpec); } setPublicKey()方法实例化PublicKey 。 此方法与setPrivateKey()方法几乎相同但让我们看一下细节。 ClassLoader用于将InputStream获取到类路径上的公钥文件。 文件的字节被读入新的String 。 接下来 String的处理如下 String stringAfter stringBefore .replaceAll( \\n , ) .replaceAll( -----BEGIN PUBLIC KEY----- , ) .replaceAll( -----END PUBLIC KEY----- , ) .trim(); 此处理是必需的因为即使我们使用OpenSSL生成具有X509编码的私钥文件该文件也不能被Java直接使用。 如果尝试不进行上述处理则会出现以下异常 java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format X509EncodedKeySpec类期望公钥为一行文本其中删除了所有注释Java代码示例…nd。 这就是进行处理的原因。 处理除去换行符和注释后将使用X509EncodedKeySpec和KeyFactory创建PublicKey 。 KeySpec keySpec new X509EncodedKeySpec(decoded); publicKey keyFactory.generatePublic(keySpec); 现在我们有了由OpenSSL生成的私钥和公钥文件创建的PrivateKey和PublicKey实例。 那么您想开始加密和解密吗 我们开始做吧 Java内存中测试 现在是时候将它们放在一起看看我们是否可以加密和解密一个值了。 但是如果没有加密和解密方法我们将无法做到这一点。 我们首先需要它们。 以下清单是我的Rsa4096类的Rsa4096 。 查看GitHub上的类或通读上面的“ Java KeyFactoryPrivateKeyPublicKey”部分以获得该类的完整源代码。 Rsa4096类包含加密和解密方法。 首先让我们看一下加密方法。 加密 清单5.1 – cryptoToBase64方法 public String encryptToBase64(String plainText) { String encoded null ; try { Cipher cipher Cipher.getInstance( RSA ); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte [] encrypted cipher.doFinal(plainText.getBytes()); encoded Base64.getEncoder().encodeToString(encrypted); } catch (Exception e) { e.printStackTrace(); } return encoded; } 清单5.1显示了encryptToBase64()方法。 该方法具有一个String参数该参数是要加密的值。 传入byte[]数组可能更健壮但是根据我的经验通常需要对String值进行加密。 当然为满足您的需求进行更新。 方法的名称和返回类型意味着将返回Base64编码的String。 传回byte[]数组可能更健壮但是根据我的经验通常需要String返回值。 当然为满足您的需求进行更新。 加密只需要PublicKey 。 解密 清单5.2 – cryptoFromBase64方法 public String decryptFromBase64(String base64EncodedEncryptedBytes) { String plainText null ; try { final Cipher cipher Cipher.getInstance( RSA ); cipher.init(Cipher.DECRYPT_MODE, privateKey); byte [] decoded Base64 .getDecoder() .decode(base64EncodedEncryptedBytes); byte [] decrypted cipher.doFinal(decoded); plainText new String(decrypted); } catch (Exception ex) { ex.printStackTrace(); } return plainText; } 清单5.2显示了cryptoFromBase64方法。 该方法具有一个String参数该参数的名称为加密的byte[]数组的Base64编码的String 。 传递byte[]数组可能会更健壮但是根据我的经验通常需要将String解密回其原始值。 当然为满足您的需求进行更新。 方法的名称和返回类型表示将返回原始的String值。 传回byte[]数组可能更健壮但是根据我的经验原始值始终是String 。 当然为满足您的需求进行更新。 只有PrivateKey需要解密。 单元测试 现在让我们看一下InMemoryTest单元测试看看是否所有功能都可以一起使用。 注意内存中的加密和解密不是我的目标之一。 目标是在应用程序外部使用OpenSSL加密并在应用程序内部使用Java解密。 但是首先尝试在内存中进行测试是确保一切正常的良好测试。 清单5.3 – InMemoryTest单元测试 package org.thoth.rsa; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; /** * * author Michael Remijan mjremijanyahoo.com mjremijan */ public class InMemoryTest { Test public void test_in_memory_encryption_decryption() throws Exception { // Setup Rsa4096 rsa new Rsa4096( ./private_key_rsa_4096_pkcs8-generated.pem , ./public_key_rsa_4096_pkcs8-exported.pem ); String expected Text to be encrypted ; // Test String encryptedAndEncoded rsa.encryptToBase64(expected); String actual rsa.decryptFromBase64(encryptedAndEncoded); // Assert Assertions.assertEquals(expected, actual); } } 清单5.3显示了InMemoryTest单元测试。 该测试最终运行所有代码并验证String是否可以加密和解密回相同的值。 首先 // Setup单元测试的// Setup指定在哪里可以找到私钥和公钥文件。 请记住这些文件是由OpenSSL生成的。 我将它们放在项目的src/test/resources/目录中以便在运行单元测试时它们将显示在类路径中。 它们用于创建我的Rsa4096类的实例。 接下来测试进行加密和解密。 似乎有点反气候但是所有工作都在Rsa4096类中。 最后JUnit断言检查期望值等于实际值。 如果一切顺利则测试应通过含义加密然后解密返回原始值。 克隆我的thoth-rsa存储库并亲自运行单元测试以查看它是否有效 因此OpenSSL生成的私钥和公钥可在Java中用于加密和解密内存中的值。 但是可以在 Java 外部使用OpenSSL对值进行加密而在应用程序内部对其进行解密吗 试试吧 加密文件 这项研究的既定目标之一是OpenSSL加密整个文件而Java应用程序将对其解密。 Java应用程序将值外部化到属性文件中非常普遍。 尽管最好只加密特定的属性在下一节中介绍但是加密整个文件是确保不丢失任何敏感属性的快速简便的方法。 首先我们需要加密整个文件。 我们已经有了用于加密的公共密钥。 因此剩下的就是正确的OpenSSL命令。 让我们看一下命令。 文件加密 清单6.1 – OpenSSL加密文件 openssl rsautl -encrypt -inkey public_key_rsa_4096_pkcs8-exported.pem -pubin -in file_unencrypted.txt | openssl enc -A -base64 file_encrypted_and_encoded.txt 清单6.1admin.2018显示了OpenSSL命令该命令用于将纯文本文件的内容加密和Base64编码为新文件。 请记住加密时仅需要公用密钥文件。 因此在处理敏感数据时可以保持职责分离。 该命令创建的file_encrypted_and_encoded.txt文件包含一个Base64编码的字符串看起来像这样 UwXBjowtfDQix2lOiBbaX6J8GayYmo5EsZuHxPUtSMW9kncnVNpeWwjpOc1yEiSanFEeRE4QQz/DKWr16LHAt4B8OMOSvXikEpnv0uvrUtKTE1KalHZDKBHvk5op44gMhhQVpyjKQrVMY/76R83o0/kj60fNsuqpx5DIH/RHhnwBCNvjpjlsvLPPlL1YqUIn0it5XCaZcTiJhpsOh2LmEhfARLgMqVGZxb0zIPvn0zPerhVSZK1wUcI4VanOj2rDOflL1Sr5eiimAaIC5/zZniIZP4RDdF3VvlMur5MzUkgxM8CkIJPxKUj8QsEPEcVt3p3/cIvR9YeBmP6Gsw78NutJH3vXAvduPIB2/z/w8iRn/NYcCRX8xZUEGcM44Ks1n7eTpUWJE1T3KfH08HOhXuMJUocaxSiZiX2ROQt/gKPJsz27b3u967y9s1DozaaJY1nKOqEbHDg/uVcgmwYXD5CDy/qAqKXRJ3dCmJWw46OwPSTMAhkBGOihDhrcQbid3O9rsTU/Od19FaOGnS55HHv/4cnIwJnKXBtziG5EaJlouu/HpoabQEoiwgcuh2OOj41Rm6nG3Ef3uxppdoXCn9x3wMDHlqc8K0Nenc2IbAM //Vd98PVwBf5/nvNyQKwfpQOFJrT4Ygyt3qWQ00cLG7u3fsngg0 大 加密文件 校验 现在这是一个大问题Java可以解密吗 让我们找出答案 单元测试 让我们看一下EncryptedFileTest单元测试。 清单6.2 – EncryptedFileTest单元测试 package org.thoth.rsa; import java.io.InputStream; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; /** * * author Michael Remijan mjremijanyahoo.com mjremijan */ public class EncryptedFileTest { protected Rsa4096 rsa; BeforeEach public void setUp() throws Exception { rsa new Rsa4096( ./private_key_rsa_4096_pkcs8-generated.pem , ./public_key_rsa_4096_pkcs8-exported.pem ); } Test public void test_encrypted_file() throws Exception { // Setup String expected getFileAsString( ./file_unencrypted.txt ); String encryptedAndEncoded getFileAsString( ./file_encrypted_and_encoded.txt ); // Test String actual rsa.decryptFromBase64(encryptedAndEncoded); System.out.printf( %s%n , actual); // Assert Assertions.assertEquals(expected, actual); } public String getFileAsString(String classPathResourceLocation) throws Exception { InputStream is this .getClass() .getClassLoader() .getResourceAsStream( classPathResourceLocation ); byte [] bytes is.readAllBytes(); is.close(); return new String(bytes); } } 首先 BeforeEach方法创建我的Rsa4096类的实例。 这将使用OpenSSL生成的私钥和公钥文件。 单元测试运行时这些密钥文件位于Java类路径上。 Rsa4096用于解码和解密加密文件的内容。 其次调用getFileAsString()帮助方法。 方法的名称准确说明了它的作用。 它在Java类路径上找到一个文件并将其内容读取为String 。 请记住OpenSSL文件加密命令既对加密也对Base64编码对输出文件的内容进行编码因此将这些内容存储为String是安全的。 第三 Rsa4096用于通过调用decryptFromBase64()进行解码和解密。 最后JUnit断言确保解码和解密成功并且测试返回原始值。 而已。 我们做到了 但这还不是全部。 当然加密整个文件很有趣但是更有趣的是仅加密文件中的特定值。 无法做到这一点……还是可以 让我们来看看。 文件中的加密值 这项研究的另一个目标是使用OpenSSL仅加密文件中的特定值。 为此必须有一个包含占位符以替换变量的起始模板文件。 它们将被加密和编码的值替换。 OpenSSL将用于加密和编码但是我们还需要使用sed进行搜索和替换。 让我们来看看。 价值加密 清单7.1 – OpenSSL加密文件中的值 sed s|XXXX|printf SECRET | openssl rsautl -encrypt -inkey public_key_rsa_4096_pkcs8-exported.pem -pubin | openssl enc -A -base64|g some_template.properties some_tmp1.properties sed s|YYYY|printf 123 - 45 - 7890 | openssl rsautl -encrypt -inkey public_key_rsa_4096_pkcs8-exported.pem -pubin | openssl enc -A -base64|g some_tmp1.properties some_app.properties 清单7.1通过管道Unix命令获得了一些信息因此让我们来一小段来看一下。 首先从some_template.properties文件开始。 这是一个标准的Java属性文件但是文件中的某些属性没有值它们具有用于替换变量的占位符 namemike colorblue passwordXXXX sizeL ssnYYYY price 4.99 如您所见 password和ssn具有用于加密敏感信息的占位符。 XXXX和YYYY应该被替换。 其次该命令的sed s|XXXX|printf SECRET部分显然会搜索并用纯文本SECRET替换XXXX 。需要注意的是由于这些命令都相互夹住因此敏感文本永远不会写入文件。 第三输出文件是some_tmp1.properties 。 该文件的名称适当因为它只是临时的 。 该模板有两个值需要替换。 第一个命令仅在XXXX上进行搜索和替换。 临时文件如下所示 namemike colorblue Passwordsh3kiZTGtvcPlY3eqnUSkICHplryBs.... sizeL ssnYYYY price 4.99 四第二个命令sed s|YYYY|printf 123-45-7890 并输入文件some_tmp1.properties输出写入。 some_app.properties的。 some_app.properties文件现在已经可以使用由于所有敏感数据均已加密编码并放置在文件中因此应用程序可以some_app.properties该文件some_app.properties现在如下所示 namemike colorblue Passwordsh3kiZTGtvcPlY3eqnUSk.... sizeL ssntrpmRDvKnnjuT6hZvObthguN3A.... price 4.99 单元测试 EncryptedValuesInPropertiesFileTest是我们要看的最后一个单元测试。 清单7.2 – EncryptedValuesInPropertiesFileTest单元测试 package org.thoth.rsa; import java.util.Properties; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; /** * * author Michael Remijan mjremijanyahoo.com mjremijan */ public class EncryptedValuesInPropertiesFileTest { protected Rsa4096 rsa; BeforeEach public void setUp() throws Exception { rsa new Rsa4096( ./private_key_rsa_4096_pkcs8-generated.pem , ./public_key_rsa_4096_pkcs8-exported.pem ); } Test public void test_encrypted_values_in_properties_file() throws Exception { // Setup Properties encryptedAndEncoded new Properties(); encryptedAndEncoded.load( this .getClass() .getClassLoader() .getResourceAsStream( ./some_app.properties ) ); // Test String passwordActual rsa.decryptFromBase64( encryptedAndEncoded.getProperty( password ) ); String ssnActual rsa.decryptFromBase64( encryptedAndEncoded.getProperty( ssn ) ); // Assert Assertions.assertEquals( SECRET , passwordActual); Assertions.assertEquals( 123-45-7890 , ssnActual); } } 清单7.2显示了EncryptedValuesInPropertiesFileTest单元测试。 该测试将读取some_app.properties文件并希望它能够解码和解密其中的值。 首先 BeforeEach方法创建我的Rsa4096类的实例。 这将使用OpenSSL生成的私钥和公钥文件。 单元测试运行时这些密钥文件位于Java类路径上。 Rsa4096用于解码和解密加密文件的内容。 其次创建一个Properties对象并调用load()以将其与属性文件的内容一起加载。 请记住在类路径上可以找到some_app.properties文件。 第三从Properties对象检索加密和编码后的值然后使用Rsa4096通过调用decryptFromBase64()对其进行解码和解密。 最后JUnit断言确保解码和解密成功并且测试返回原始值。 而已。 我们做到了 我们设定要实现的所有目标均已实现。 只是为了确保让我们回顾一下。 摘要 本博客的目的是演示Java与OpenSSL的互操作性 使用OpenSSL生成私钥和公钥 使用OpenSSL加密值 用Java解密值 我能够通过定义和实现以下目标来证明这一点 选择的加密工具是OpenSSL。 它在每个Linux / Unix系统上都是行业标准并且对于所有DevOps团队都是熟悉的。 我演示了执行所有必需操作的OpenSSL命令。 在某些情况下 openssl不能独自完成所有操作该命令已通过管道传递给sed等其他标准Linux / Unix工具。 由DevOps或其他团队执行的加密因此职责分离。 开发团队中没有人会知道未加密的价值。 我演示了此示例其中显示了分别用于生成私钥和公钥文件以及用于加密文件或值的命令。 作为单独的命令如果需要可以将职责分开。 所有环境都将使用自己的密钥。 没有密钥共享。 我通过展示执行用于生成密钥的命令有多么容易来证明了这一点。 这些命令甚至可以由基础结构作为每个环境的编码过程来自动化。 可以随时重新生成所有密钥和加密值而无需更改应用程序。 当运行单元测试时Maven可以轻松地将文件添加到类路径中而我正是利用这一点来开发测试。 我希望很明显即使您像我一样使用类路径策略重新生成所有密钥和加密值也是微不足道的。 重新启动应用程序将重新读取所有内容。 无需更改应用程序。 请记住您可以创建自己的策略并编写代码以支持该策略这也使“无变化”目标成为不可能……请不要这样做) 加密将是整个文件或属性文件中的特定值。 我用OpenSSL命令演示了这两者。 我还提供了EncryptedFileTest和EncryptedValuesInPropertiesFileTest单元测试以证明其有效。 使用DevOps和开发团队共同商定并实施的策略加密的值和密钥可用于Java运行时。 我通过确定我的代码将利用Maven的将文件放在类路径中的能力来证明这一点。 因此我的策略是从类路径中读取文件。 当然您可以决定自己的策略并更新代码以支持它。 Java应用程序出于其所需的任何目的执行解密。 不要记录加密值 我用Rsa4096类演示了这一点该类执行解码和解密。 另外-这非常重要-我从不记录任何Rsa4096类或单元测试中的解码和解密值。 而已 感谢您和我一起旅行。 这是一个有趣的研究主题我希望您通过阅读这篇文章能找到一些价值。 给我发电子邮件或发表评论让我知道。 参考文献 RemijanM.2017年12月22日。 选择Java加密算法第3部分–公钥/私钥非对称加密。 取自http://mjremijan.blogspot.com/2017/12/choosing-java-cryptographic-algorithms_5.html 。 java.security.PrivateKey的 Java代码示例。 nd取自http://www.javased.com/index.php?apijava.security.PrivateKey 德斯坦 2017年10月1日。 ParseRSAKeys.java。 取自https://gist.github.com/destan/b708d11bd4f403506d6d5bb5fe6a82c5 管理员。 2018年8月21日。 在Linux上使用OpenSSL加密消息和文件。 取自https://linuxconfig.org/using-openssl-to-encrypt-messages-and-files-on-linux java.security.spec.PKCS8EncodedKeySpec的Java代码示例。 nd取自https://www.programcreek.com/java-api-examples/java.security.spec.PKCS8EncodedKeySpec 翻译自: https://www.javacodegeeks.com/2020/04/encrypt-with-openssl-decrypt-with-java-using-openssl-rsa-public-private-keys.html
http://wiki.neutronadmin.com/news/313709/

相关文章:

  • 信誉好的低价网站建设国内做网站的公司
  • 建设网站的企业邮箱优秀网站要素
  • 那个做图网站叫什么廊坊网站制作潍坊公司电话
  • 一般网站用什么做的织梦模板栏目页文件在哪
  • 合肥建站网站模板国外做ppt的网站有哪些
  • 如何拿到网站后台密码网站建设预算和维护
  • 哪个网站有学做内帐的视频旅游响应式网站建设
  • 深圳网站建设网络推广哪里有个人品牌营销公司
  • 网站的开发公司倒闭对网站使用软件著作权
  • 深圳网站运营托管网站多语言切换
  • 国家重大项目建设库网站com域名网站排名优先
  • 北京响应式网站建设费用校园网站建设实施方案
  • 做网站需要懂什么ps制作网站首页界面
  • 网站建设中的主要功能广告制作安装工
  • 建设互联网地方垂直网站新手制作网站
  • 网站文案技巧网站建设购买数据库的流程
  • 做网站常用的技术有哪些网站信息备案查询
  • 淘宝开放平台怎么做淘宝客网站微信开发平台公司
  • 企业互联网网站定位上海企业网站制作电话
  • 做画册封面的网站辽宁建设工程信息网直接发包工程
  • 网站建设进什么分录怎么做网站表白
  • 广州网站优化网站地推团队联系方式
  • 开发区二手房北京大型网站优化
  • 大庆商城网站建设建设商城类网站多少钱
  • 如何用书签 做网站接口wordpress怎么调用音频
  • 如何建设物流网站网站的制
  • 北京建设银行支行查询官方网站模板做图 网站有哪些内容
  • 企业的网站建设网站开发 工期安排
  • 网站备案 必须在接入商处工程建设项目在哪个网站查询
  • 建设电子商务网站的试卷东莞市的网站公司哪家好