| # 如果我们把a看成甲的私钥,A看成甲的公钥,b看成乙的私钥,B看成乙的公钥 |
| # DH算法的本质就是双方各自生成自己的私钥和公钥,私钥仅对自己可见,然后交换公钥,并根据自己的私钥和对方的公钥,生成最终的密钥secretKey |
| # DH算法通过数学定律保证了双方各自计算出的secretKey是相同的 |
| |
| import java.math.BigInteger; |
| import java.security.*; |
| import java.security.spec.*; |
| import javax.crypto.KeyAgreement; |
| |
| public class Main { |
| |
| public static void main(String[] args) { |
| |
| Person bob = new Person("Bob"); |
| Person alice = new Person("Alice"); |
| |
| |
| bob.generateKeyPair(); |
| alice.generateKeyPair(); |
| |
| |
| |
| bob.generateSecretKey(alice.publicKey.getEncoded()); |
| |
| alice.generateSecretKey(bob.publicKey.getEncoded()); |
| |
| |
| bob.printKeys(); |
| alice.printKeys(); |
| |
| } |
| } |
| |
| class Person { |
| |
| public final String name; |
| |
| public PublicKey publicKey; |
| private PrivateKey privateKey; |
| private byte[] secretKey; |
| |
| public Person(String name) { |
| this.name = name; |
| } |
| |
| |
| public void generateKeyPair() { |
| try { |
| KeyPairGenerator kpGen = KeyPairGenerator.getInstance("DH"); |
| kpGen.initialize(512); |
| KeyPair kp = kpGen.generateKeyPair(); |
| this.privateKey = kp.getPrivate(); |
| this.publicKey = kp.getPublic(); |
| } catch (GeneralSecurityException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| public void generateSecretKey(byte[] receivedPubKeyBytes) { |
| try { |
| |
| X509EncodedKeySpec keySpec = new X509EncodedKeySpec(receivedPubKeyBytes); |
| KeyFactory kf = KeyFactory.getInstance("DH"); |
| PublicKey receivedPublicKey = kf.generatePublic(keySpec); |
| |
| KeyAgreement keyAgreement = KeyAgreement.getInstance("DH"); |
| keyAgreement.init(this.privateKey); |
| keyAgreement.doPhase(receivedPublicKey, true); |
| |
| this.secretKey = keyAgreement.generateSecret(); |
| } catch (GeneralSecurityException e) { |
| throw new RuntimeException(e); |
| } |
| } |
| |
| public void printKeys() { |
| System.out.printf("Name: %s\n", this.name); |
| System.out.printf("Private key: %x\n", new BigInteger(1, this.privateKey.getEncoded())); |
| System.out.printf("Public key: %x\n", new BigInteger(1, this.publicKey.getEncoded())); |
| System.out.printf("Secret key: %x\n", new BigInteger(1, this.secretKey)); |
| } |
| } |
| |
| # 控制台 |
| Name: Bob |
| Private key: 3081d202010030819706092a864886f70d010301308189024100fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e170240678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4020201800433023100c357c532edcd57209f23e75fd6817b7ee285275de2f5f52b2dfafaa5c312765161115251938f51f3d42404d5f72181ba |
| Public key: 3081df30819706092a864886f70d010301308189024100fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e170240678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca402020180034300024027bdc2d77084fbc4f7d43c561d0ddedb7f5213df9c22205da446a7f6c882979e099c3408dfc06d99bb96615dc76892d398620d0a16a7bf4e893d6a2aa58d88e3 |
| Secret key: 6c0293377588bf404464859ccdc3daace562ae28e9f57a8b8902fe8236922db358de5c3c0d10d2aad96f82415b0d0b67d5cd3892424b7eaa627b3cc2d7bde42f |
| Name: Alice |
| Private key: 3081d202010030819706092a864886f70d010301308189024100fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e170240678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4020201800433023100b5a2be00c11885fb86f27a14b0fd6490e233bc9377706074a13b78cc5bfceb02d3187e0acb5a2b57175837032b8d4315 |
| Public key: 3081df30819706092a864886f70d010301308189024100fca682ce8e12caba26efccf7110e526db078b05edecbcd1eb4a208f3ae1617ae01f35b91a47e6df63413c5e12ed0899bcd132acd50d99151bdc43ee737592e170240678471b27a9cf44ee91a49c5147db1a9aaf244f05a434d6486931d2d14271b9e35030b71fd73da179069b32e2935630e1c2062354d0da20a6c416e50be794ca4020201800343000240271b19a0db8ee723824a3f19d0383b0d8aaffe26e4c075b8f2a5808d4d76029d4734f1eb8979f8ae7df6163dc0bca8486a76ddef63b6b422da807970a97e9bdf |
| Secret key: 6c0293377588bf404464859ccdc3daace562ae28e9f57a8b8902fe8236922db358de5c3c0d10d2aad96f82415b0d0b67d5cd3892424b7eaa627b3cc2d7bde42f |
| # 非对称加密总是和对称加密一起使用 |
| # 假设小明需要给小红需要传输加密文件,他俩首先交换了各自的公钥; |
| # 小明生成一个随机的AES口令,然后用小红的公钥通过RSA加密这个口令,并发给小红; |
| # 小红用自己的RSA私钥解密得到AES口令; |
| # 双方使用这个共享的AES口令用AES加密通信。 |
| |
| import java.math.BigInteger; |
| import java.security.*; |
| import javax.crypto.Cipher; |
| |
| public class Main { |
| public static void main(String[] args) throws Exception { |
| |
| byte[] plain = "Hello,使用RSA非对称加密算法对数据进行加密!".getBytes("UTF-8"); |
| |
| Person alice = new Person("Alice"); |
| |
| byte[] pk = alice.getPublicKey(); |
| System.out.println(String.format("public key: %x", new BigInteger(1, pk))); |
| byte[] encrypted = alice.encrypt(plain); |
| System.out.println(String.format("encrypted: %x", new BigInteger(1, encrypted))); |
| |
| byte[] sk = alice.getPrivateKey(); |
| System.out.println(String.format("private key: %x", new BigInteger(1, sk))); |
| byte[] decrypted = alice.decrypt(encrypted); |
| System.out.println(new String(decrypted, "UTF-8")); |
| } |
| } |
| |
| class Person { |
| String name; |
| |
| PrivateKey sk; |
| |
| PublicKey pk; |
| |
| public Person(String name) throws GeneralSecurityException { |
| this.name = name; |
| |
| KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA"); |
| kpGen.initialize(1024); |
| KeyPair kp = kpGen.generateKeyPair(); |
| this.sk = kp.getPrivate(); |
| this.pk = kp.getPublic(); |
| } |
| |
| |
| public byte[] getPrivateKey() { |
| return this.sk.getEncoded(); |
| } |
| |
| |
| public byte[] getPublicKey() { |
| return this.pk.getEncoded(); |
| } |
| |
| |
| public byte[] encrypt(byte[] message) throws GeneralSecurityException { |
| Cipher cipher = Cipher.getInstance("RSA"); |
| cipher.init(Cipher.ENCRYPT_MODE, this.pk); |
| return cipher.doFinal(message); |
| } |
| |
| |
| public byte[] decrypt(byte[] input) throws GeneralSecurityException { |
| Cipher cipher = Cipher.getInstance("RSA"); |
| cipher.init(Cipher.DECRYPT_MODE, this.sk); |
| return cipher.doFinal(input); |
| } |
| } |
| |
| # 控制台 |
| public key: 30819f300d06092a864886f70d010101050003818d003081890281810089660a2d7d6fce9cacca4b6c31e7815dbd3b25109c9f54776f00fef6cd5e6b6e68237cbfa8fd5476a19ad2ab19f3c393e9a14ab65aca68b4c2bac2499613710b6c2af2d3243c7af7f03829c8a4512626529c0b887740d07ef9c2c10c454d9c971619eb307df092122cb27f36396eeae828e777e97ff38c27cb87ba5936a4db1b0203010001 |
| encrypted: 184a4bd4faa5d3ceae2c08d393ab48b928f6ace0086a2d4a7715fff012b6c0d3483ab842e8cf476ed6df0aa9cd0161c7c04d6c02e1a44a8f013c27a653bb4fe74cf1b1220f23caeb78ea5dec39b9ec842a4a16a3a532400ff6253723574624ebfb213e028dc12164a531cbee34db9df66ff2b883600de8526d3bf5b19ee9e642 |
| private key: 30820276020100300d06092a864886f70d0101010500048202603082025c0201000281810089660a2d7d6fce9cacca4b6c31e7815dbd3b25109c9f54776f00fef6cd5e6b6e68237cbfa8fd5476a19ad2ab19f3c393e9a14ab65aca68b4c2bac2499613710b6c2af2d3243c7af7f03829c8a4512626529c0b887740d07ef9c2c10c454d9c971619eb307df092122cb27f36396eeae828e777e97ff38c27cb87ba5936a4db1b02030100010281810087a4d14f6f92bdeb373acf9315017459d2c35d283537a6eff20a8daba1bc215b723bf6a0507928b5a57d6f95b39d4febeaae6d4ff1f9f9bcdab1fdb52010397c9634aa3e87003afe4a2cc6f2169fcf6e163d3d3593b22fc08585a9822f887b0b28a0a721ff119ff3408dd6ad040373fffdb4d6264ce70bee95338bbe52d9bf21024100c8cd1d32bb0c06d275041d6fb5bf11b25957f63d4ed93ffef110d8cd1e8a6c5c9fc138bfea49fe448db0f6138605acd0405ba3398dcc3b86cd868fb50538933f024100af2b1f92b32b4946f76282f567fcae8533dc1a48a34508487e0aeff479dbe24c55081773cbf6daf10e379e85aff98d5741b62f2432bce03439ade9d2a68aad2502400db47a2eb13783ebaf52e5936f4b28310d0a04e37053419bebe62375f484ac1ab248a4cfec74ba670168b792e38dd59aad19d40d249170eaa5726eb28335b64f02403c9f47010542f0cc3fa7773d292cd8d53e9a68fa448f0a8bd41b42ea30163a1e42bb572a7b2746a470502d6b84f86fc307f9de1cbff67ffd730cce4459e0da8502404c0e26dd68bc647f65d74480e048204c898a1e2a3fcd0bb46c87354c4c97bd92c03820616c924c1998913c43d91e74b54be3ce2530627cda19e32f348180c246 |
| Hello,使用RSA非对称加密算法对数据进行加密! |
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术
2021-05-07 vue2.0入门