有人说为什么有了对称加密,为什么还要有个非对称加密,那么首先我们来说说这俩种加密的优缺点。
优点:对称加密算法通常比非对称加密算法更快,更适合加密大量数据。
缺点:因为同一个密钥需要用于加密和解密,所以密钥的安全分发和存储是个至关重要的问题。如果密钥泄露,加密的数据就会被轻易解密。
非对称加密:
优点:如我们上方所说非对称加密采用一对密钥来加密,可以大大增强数据的完整性和真实性,而且,非对称加密还可以用于数字签名。
缺点:非对称加密算法相对来说没有对称加密快速,所以它不适合加密大量数据。此外,如果私钥你不小心丢了,那么加密的数据,怎么解密都没有办法解密。
说了这么多,了解了俩种加密方式,我们来了解一下,非对称加密有哪几种常见的加密方式。
import javax.crypto.Cipher;import java.security.*;import java.util.Base64;public class RSAEncryptionDemo {public static void main(String[] args) throws Exception {// 创建RSA密钥对生成器KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");keyPairGenerator.initialize(2048);KeyPair keyPair = keyPairGenerator.generateKeyPair();// 获取公钥和私钥PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();// 创建RSA加密对象Cipher cipher = Cipher.getInstance("RSA");// 加密数据cipher.init(Cipher.ENCRYPT_MODE, publicKey);String originalText = "Hello, World!";byte[] encryptedBytes = cipher.doFinal(originalText.getBytes());String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes);System.out.println("加密后: " + encryptedText);// 解密数据cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));String decryptedText = new String(decryptedBytes);System.out.println("解密后: " + decryptedText);}}
加密后: aaMWUd65otrubkskidn3yhpLb9H1gbXi836X8eGJKxqWbJypNZRFi0cgTvpynqdu1wSRJoPtRys9bQDA9OvfHfQ98ZUUpa1NMhl8ptNyl0wMZwQiUrUg5qh/ekRmZseTPcz6nQYIhmYYkRhof7Le/S2Qx6kCmOX+m1LpjagDrVV9rOj2QkaOje5ugd7YxDLGa25e++aWKYZFFAU4QVYeO8avkUCCQ93xff9xYD20ecjkHgW8Brox6NzB62edxC3UJEbAkadU51t0J7h+qeVee+r2djg7hDQyTB0XKjSo1ub+BHbjxADv/SlkVZ+rLcEY1jzoAL+VZQ4cPK+//IBPSg==解密后: Hello, World!
通过代码示例,我们可以看到使用KeyPairGenerator生成一个RSA密钥对。然后,我们使用Cipher对象来加密和解密文本数据。加密后的数据被转换为Base64编码的字符串,以便于打印和传输。
import java.security.*;import java.util.Base64;public class DSADemo {public static void main(String[] args) throws Exception {// 创建DSA密钥对生成器KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");keyPairGenerator.initialize(2048);KeyPair keyPair = keyPairGenerator.generateKeyPair();// 获取公钥和私钥PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();// 创建DSA签名对象Signature signature = Signature.getInstance("SHA256withDSA");// 签署数据signature.initSign(privateKey);String data = "Hello, World!";signature.update(data.getBytes());byte[] sign = signature.sign();String signedData = Base64.getEncoder().encodeToString(sign);System.out.println("加密后: " + signedData);// 验证签名signature.initVerify(publicKey);signature.update(data.getBytes());boolean isValid = signature.verify(Base64.getDecoder().decode(signedData));System.out.println("解密后是否正确: " + isValid);}}
加密后: MDwCHG0RYpNu4n26fSjUPpPpIVmimgCR1oxp4XO2ndYCHATQ7ZvUqQImU2uPCRdB8zTG444ZFqG7T0/Q9Wo=解密后: true
看示例中,我们首先使用KeyPairGenerator生成一个DSA密钥对。然后,我们使用Signature对象来创建数字签名并验证签名。签名和验证过程中,我们使用了SHA-256消息摘要算法与DSA结合使用。
我们来看下示例:
import java.security.*;import java.security.spec.ECGenParameterSpec;import java.util.Base64;public class ECCDemo {public static void main(String[] args) throws Exception {// 创建ECC密钥对生成器KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("EC");// 使用secp256r1曲线keyPairGenerator.initialize(new ECGenParameterSpec("secp256r1"));KeyPair keyPair = keyPairGenerator.generateKeyPair();// 获取公钥和私钥PublicKey publicKey = keyPair.getPublic();PrivateKey privateKey = keyPair.getPrivate();// 创建ECC签名对象Signature signature = Signature.getInstance("SHA256withECDSA");// 签署数据signature.initSign(privateKey);String data = "Hello, World!";signature.update(data.getBytes());byte[] sign = signature.sign();String signedData = Base64.getEncoder().encodeToString(sign);System.out.println("签名数据: " + signedData);// 验证签名signature.initVerify(publicKey);signature.update(data.getBytes());boolean isValid = signature.verify(Base64.getDecoder().decode(signedData));System.out.println("解签是否正确: " + isValid);}}
签名数据: MEUCIQC6l89xlLGg5ad1wZgao5+SoYzkYvbWTK1LNzBihXp/TwIgWjc3xv4Asi+gJ8C6MkyYxUnAP+rPdSOxRXF56RRVepQ=解签是否正确: true
示例中,我们首先使用KeyPairGenerator和ECGenParameterSpec生成一个ECC密钥对。然后,我们使用Signature对象来创建数字签名并验证签名。签名和验证过程中,我们使用了SHA-256消息摘要算法与ECDSA结合使用。
请注意,ECC算法仅用于创建和验证数字签名,它不适用于数据加密。如果需要加密数据,应该使用对称加密或非对称加密算法。此外,ECC的安全性取决于所使用的椭圆曲线和实现的细节。
import javax.crypto.KeyAgreement;import javax.crypto.spec.DHParameterSpec;import java.security.AlgorithmParameterGenerator;import java.security.AlgorithmParameters;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.util.Base64;public class DiffieHellmanDemo {public static void main(String[] args) throws Exception {// 生成Diffie-Hellman参数AlgorithmParameterGenerator paramGen = AlgorithmParameterGenerator.getInstance("DH");paramGen.init(2048);AlgorithmParameters params = paramGen.generateParameters();DHParameterSpec dhParams = params.getParameterSpec(DHParameterSpec.class);// 生成Alice的密钥对KeyPairGenerator aliceKpairGen = KeyPairGenerator.getInstance("DH");aliceKpairGen.initialize(dhParams);KeyPair aliceKpair = aliceKpairGen.generateKeyPair();// 生成Bob的密钥对KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH");bobKpairGen.initialize(dhParams);KeyPair bobKpair = bobKpairGen.generateKeyPair();// Alice的密钥交换KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH");aliceKeyAgree.init(aliceKpair.getPrivate());aliceKeyAgree.doPhase(bobKpair.getPublic(), true);// Bob的密钥交换KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH");bobKeyAgree.init(bobKpair.getPrivate());bobKeyAgree.doPhase(aliceKpair.getPublic(), true);// 生成共享密钥byte[] aliceSharedSecret = aliceKeyAgree.generateSecret();byte[] bobSharedSecret = bobKeyAgree.generateSecret();// 输出共享密钥String aliceKey = Base64.getEncoder().encodeToString(aliceSharedSecret);System.out.println("Alice's的共享密钥: " + aliceKey);String bobKey = Base64.getEncoder().encodeToString(bobSharedSecret);System.out.println("Bob's 的共享密钥: " + bobKey);System.out.println("密钥是否相同: " + bobKey.equals(aliceKey));}}
Alice's的共享密钥: sW3xY/Vqn+fBuv4PRKWozaK+V66I4jKvEa8qCcmz/6vEx6a4pk2jzVsFVNRfoCx7mYGbEqBYz1YJSCCNZOuG1VApeN43Cp5YiFr3BcUZQF+51fZf9IYopOxLWeA68J3dKx9SdSgYRkhEI4zWJC+RS6jaf5ElFT/duzVxCrzYbabptvcWsxHhi40TvBcDHpUCbO4OXeYiDgUPuOJYfJTeZrwybVppOqgQH46JIw6EBnu8jWXFX14XuncgIqCdDrA/Etp2G7aKX+7nsow5zPKI+dzw1CN9kSzWUuy4GiCT4AEqvgOUecg5qMfSGLzu4CNacIkBFtAaM5gXrFr2m1gsXg==Bob's 的共享密钥: sW3xY/Vqn+fBuv4PRKWozaK+V66I4jKvEa8qCcmz/6vEx6a4pk2jzVsFVNRfoCx7mYGbEqBYz1YJSCCNZOuG1VApeN43Cp5YiFr3BcUZQF+51fZf9IYopOxLWeA68J3dKx9SdSgYRkhEI4zWJC+RS6jaf5ElFT/duzVxCrzYbabptvcWsxHhi40TvBcDHpUCbO4OXeYiDgUPuOJYfJTeZrwybVppOqgQH46JIw6EBnu8jWXFX14XuncgIqCdDrA/Etp2G7aKX+7nsow5zPKI+dzw1CN9kSzWUuy4GiCT4AEqvgOUecg5qMfSGLzu4CNacIkBFtAaM5gXrFr2m1gsXg==密钥是否相同: true
示例中,我们首先使用AlgorithmParameterGenerator生成Diffie-Hellman参数。然后,我们为Alice和Bob生成各自的密钥对。接着,我们使用KeyAgreement对象来执行密钥交换,最终生成共享密钥。
请注意,Diffie-Hellman密钥交换协议仅用于交换密钥,它不直接用于加密或解密数据。交换得到的共享密钥通常用作对称加密算法的密钥,用于加密实际传输的数据。
原创文章,作者:guozi,如若转载,请注明出处:https://www.sudun.com/ask/78246.html