大家好,欢迎来到IT知识分享网。
1. 算法概述
ElGamal算法和ECC算法基于离散对数问题建立。与典型非对称加密算法RSA算法相比,ElGamal算法则被称为常用非对称加密算法。
ElGamal既可用于加密,又可用于数字签名,是除RSA算法外最具代表性的公钥加密算法之一。
ElGamal算法就有较好的安全性,被广发应用。著名的美国数字签名标准(Digital Signature Standard, DSS)就是采用ElGamal签名方案的一种变形——DSA(Digital Signature Algorithm)。
2. 模型分析
- 构建并发布密钥
1、2步骤为构建密钥流程
- 使用密钥进行加密消息的交互
3、4、5为使用密钥进行加密消息交互
Bouncy Castle提供的ElGamal算法实现遵循 “公钥加密, 私钥解密”的加密/解密方式。
3. 代码实现
Bouncy Castle对ElGamal算法具体实现细节如下:
算法 | 密钥长度 | 密钥默认长度 | 工作模式 | 填充模式 | 备注 |
---|---|---|---|---|---|
ElGamal | 160~16384位(密钥长度为8的整数倍) | 1024 | ECB、NONE | NoPadding、PKCS1Padding、OAEPWithMD5AndMGF1Padding、OAEPWithSHA1AndMGF1Padding、OAEPWithSHA224AndMGF1Padding、OAEPWithSHA256AndMGF1Padding、OAEPWithSHA384AndMGF1Padding、OAEPWithSHA512AndMGF1Padding、ISO9796-1Padding | Bouncy Castle实现 |
3.1 算法实现
package com.calvin.android.demo2.secrity; import android.util.Log; import org.bouncycastle.jce.provider.BouncyCastleProvider; import java.security.AlgorithmParameterGenerator; import java.security.AlgorithmParameters; import java.security.Key; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.Provider; import java.security.PublicKey; import java.security.SecureRandom; import java.security.Security; import java.security.spec.PKCS8EncodedKeySpec; import java.security.spec.X509EncodedKeySpec; import java.util.HashMap; import java.util.Map; import javax.crypto.Cipher; import javax.crypto.spec.DHParameterSpec; / * Author:cl * Email: * Date:20-10-20 */ public class ElGamalCoder {
//非对称加密密钥算法 public static final String KEY_ALGORITHM = "ElGamal"; private static final int KEY_SIZE = 256; private static final String PUBLIC_KEY = "ElGamalPublicKey"; private static final String PRIVATE_KEY = "ElGamalPrivateKey"; / * 私钥解密 * @param data 待解密数据 * @param key 私钥 * @return byte[] 解密数据 * @throws Exception 异常 */ public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {
//取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM ); //生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); //对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, privateKey); return cipher.doFinal(data); } / * 私钥加密 * @param data 待加密数据 * @param key 私钥 * @return byte[] 加密数据 * @throws Exception 异常 */ public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception {
//取得私钥 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); //生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec); //对数据加密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, privateKey); return cipher.doFinal(data); } / * 公钥解密 * @param data 待解密数据 * @param key 公钥 * @return byte[] 解密数据 * @throws Exception 异常 */ public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception {
//取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); //生成公钥 PublicKey publicKey = keyFactory.generatePublic(x509KeySpec); //对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.DECRYPT_MODE, publicKey); return cipher.doFinal(data); } / * 公钥加密 * @param data 待加密数据 * @param key 公钥 * @return byte[] 加密数据 * @throws Exception 异常 */ public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception {
//取得公钥 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key); KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); //生成公钥 PublicKey publicKey = keyFactory.generatePublic(x509KeySpec); //对数据解密 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); cipher.init(Cipher.ENCRYPT_MODE, publicKey); return cipher.doFinal(data); } private static final String TAG = "ElGamalCoder"; public static Map<String, Object> initKey() throws Exception {
//实例化BC Provider, Android系统支持BC Provider, 这里将系统可能是旧的版本去掉,加入新版本的BC Provider Provider bcProvider = new BouncyCastleProvider(); Security.removeProvider("BC"); Security.addProvider(bcProvider); / Provider[] providers = Security.getProviders(); for (Provider provider: providers){ Log.d(TAG, "provider name = "+provider); for (Map.Entry<Object, Object> entry: provider.entrySet()){ Log.d(TAG, "\t "+entry.getKey()+", "+entry.getValue()); } } / AlgorithmParameterGenerator apg = AlgorithmParameterGenerator.getInstance(KEY_ALGORITHM, bcProvider); //初始化算法参数生成器 apg.init(KEY_SIZE); //生成算法参数 AlgorithmParameters algorithmParameters = apg.generateParameters(); //构建参数材料 DHParameterSpec elParams = (DHParameterSpec)algorithmParameters.getParameterSpec(DHParameterSpec.class); //实例化密钥对生成器 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM); //初始化密钥对生辰其 keyPairGen.initialize(elParams,new SecureRandom()); //生成密钥对 KeyPair keyPair = keyPairGen.generateKeyPair(); //公钥 PublicKey publicKey = keyPair.getPublic(); //私钥 PrivateKey privateKey = keyPair.getPrivate(); //封装密钥 Map<String, Object> keyMap = new HashMap<>(2); keyMap.put(PUBLIC_KEY, publicKey); keyMap.put(PRIVATE_KEY, privateKey); return keyMap; } public static byte[] getPublicKey(Map<String, Object> keyMap){
return ((Key)keyMap.get(PUBLIC_KEY)).getEncoded(); } public static byte[] getPrivateKey(Map<String, Object> keyMap){
return ((Key)keyMap.get(PRIVATE_KEY)).getEncoded(); } }
3.2 测试代码
@Test public void testElGamal() throws Exception {
Map<String, Object> keyMap = ElGamalCoder.initKey(); //公钥 byte[] elgamalPubKey = ElGamalCoder.getPublicKey(keyMap); //私钥 byte[] elgamalpriKey = ElGamalCoder.getPrivateKey(keyMap); System.out.println("公钥:\t"+ Base64.encodeToString(elgamalPubKey, Base64.DEFAULT)); System.out.println("私钥:\t"+ Base64.encodeToString(elgamalpriKey, Base64.DEFAULT)); String inputStr = "ElGamal加密"; byte[] data = inputStr.getBytes(); System.out.println("原文:\t"+ inputStr); byte[] encodedData = ElGamalCoder.encryptByPublicKey(data, elgamalPubKey); System.out.println("加密后:\t"+ Base64.encodeToString(encodedData,Base64.DEFAULT)); byte[] decodedData = ElGamalCoder.decryptByPrivateKey(encodedData, elgamalpriKey); String outputStr = new String(decodedData); System.out.println("解密后:\t"+ outputStr); assertEquals(inputStr,outputStr); }
3.3 运行结果
2020-10-20 17:02:17.013 11052-11067/com.calvin.android.demo2 I/System.out: 公钥: MHcwUAYGKw4HAgEBMEYCIQD/GaVs/HmUpVVOtSF8C0t/OcPNEHO83sjCdvdhkBM5fwIhAKkFaKSP 2020-10-20 17:02:17.013 11052-11067/com.calvin.android.demo2 I/System.out: nrJIz2duJFVY+kEstf31SVuOlLmyt93MghofAyMAAiAKp+k1o2R5ZlBcUvOGwVPl4xtbNjNM6yHi 2020-10-20 17:02:17.013 11052-11067/com.calvin.android.demo2 I/System.out: 4lD2+/1Omw== 2020-10-20 17:02:17.013 11052-11067/com.calvin.android.demo2 I/System.out: 私钥: MHoCAQAwUAYGKw4HAgEBMEYCIQD/GaVs/HmUpVVOtSF8C0t/OcPNEHO83sjCdvdhkBM5fwIhAKkF 2020-10-20 17:02:17.013 11052-11067/com.calvin.android.demo2 I/System.out: aKSPnrJIz2duJFVY+kEstf31SVuOlLmyt93MghofBCMCIQDQXbdvrfhkLAfMEGvsLtbawlxsg+ 2020-10-20 17:02:17.013 11052-11067/com.calvin.android.demo2 I/System.out: wydVKsyJKgZpyg== 2020-10-20 17:02:17.013 11052-11067/com.calvin.android.demo2 I/System.out: 原文: ElGamal加密 2020-10-20 17:02:17.019 11052-11067/com.calvin.android.demo2 I/System.out: 加密后: Rx58tvdX4HHKSlAFjTAxRnB0UwZL3L2IVzeQ+KlG7MuBkNRn7hAQ4KKLi/tgTmYDmDsia7VVDEbU 2020-10-20 17:02:17.019 11052-11067/com.calvin.android.demo2 I/System.out: pLGxfKSoHw== 2020-10-20 17:02:17.021 11052-11067/com.calvin.android.demo2 I/System.out: 解密后: ElGamal加密
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/129923.html