结合了两个大佬的代码,目前应该都是第一个大佬的代码
第一个Android_国密_SM2、SM3、SM4_ylineyline的专栏-优快云博客
第二个Android常用加密库集合_lambert_Lei的专栏-优快云博客
首先导入包:Android_国密_SM2、SM3、SM4_ylineyline的专栏-优快云博客
implementation 'org.bouncycastle:bcprov-jdk16:1.46'
接下来,都是自定义的东西不要找SM2的包在哪,SM2是自己的类
package com.iqilu.phonetoken.utils;
import android.text.TextUtils;
import org.bouncycastle.crypto.generators.ECKeyPairGenerator;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECKeyGenerationParameters;
import org.bouncycastle.math.ec.ECCurve;
import org.bouncycastle.math.ec.ECFieldElement;
import org.bouncycastle.math.ec.ECFieldElement.Fp;
import org.bouncycastle.math.ec.ECPoint;
import java.math.BigInteger;
import java.security.SecureRandom;
public class SM2 {
// 正式参数
public static final String[] ecc_param = {
"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF",
"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC",
"28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93",
"FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123",
"32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7",
"BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0"
};
public final BigInteger ecc_p;
public final BigInteger ecc_a;
public final BigInteger ecc_b;
public final BigInteger ecc_n;
public final BigInteger ecc_gx;
public final BigInteger ecc_gy;
public final ECCurve ecc_curve;
public final ECPoint ecc_point_g;
public final ECDomainParameters ecc_bc_spec;
public final ECKeyPairGenerator ecc_key_pair_generator;
public final ECFieldElement ecc_gx_fieldelement;
public final ECFieldElement ecc_gy_fieldelement;
public SM2() {
this.ecc_p = new BigInteger(ecc_param[0], 16);
this.ecc_a = new BigInteger(ecc_param[1], 16);
this.ecc_b = new BigInteger(ecc_param[2], 16);
this.ecc_n = new BigInteger(ecc_param[3], 16);
this.ecc_gx = new BigInteger(ecc_param[4], 16);
this.ecc_gy = new BigInteger(ecc_param[5], 16);
this.ecc_gx_fieldelement = new Fp(this.ecc_p, this.ecc_gx);
this.ecc_gy_fieldelement = new Fp(this.ecc_p, this.ecc_gy);
this.ecc_curve = new ECCurve.Fp(this.ecc_p, this.ecc_a, this.ecc_b);
this.ecc_point_g = new ECPoint.Fp(this.ecc_curve, this.ecc_gx_fieldelement, this.ecc_gy_fieldelement);
this.ecc_bc_spec = new ECDomainParameters(this.ecc_curve, this.ecc_point_g, this.ecc_n);
this.ecc_key_pair_generator = new ECKeyPairGenerator();
this.ecc_key_pair_generator.init(new ECKeyGenerationParameters(this.ecc_bc_spec, new SecureRandom()));
}
/**
* 解密
* @param value 需要解密数据(默认传入为16进制数据)
* @param key 密钥(需要16进制字符串,其他编码请使用byte[])
* @return
*/
public String simpleDeCode(String value, String key) {
if(TextUtils.isEmpty(value)|| TextUtils.isEmpty(key)){
return null;
}
byte[] datas=Utils.hexStringToBytes(value);
byte[] keyBytes=Utils.hexStringToBytes(key);
return new String(deCode(datas,keyBytes));
}
public byte[] deCode(byte[] value, byte[] key) {
if (value==null||key==null)
{
return null;
}
//加密字节数组转换为十六进制的字符串 长度变为value.length * 2
String data = Utils.byteToHex(value);
/***分解加密字串
* (C1 = C1标志位2位 + C1实体部分128位 = 130)
* (C2 = encryptedData.length * 2 - C1长度 - C2长度)
* (C3 = C3实体部分64位 = 64)
*/
byte[] c1Bytes = Utils.hexToByte(data.substring(0,130));
int c2Len = value.length - 97;
byte[] c2 = Utils.hexToByte(data.substring(130,130 + 2 * c2Len));
byte[] c3 = Utils.hexToByte(data.substring(130 + 2 * c2Len,194 + 2 * c2Len));
BigInteger userD = new BigInteger(1, key);
//通过C1实体字节来生成ECPoint
ECPoint c1 =ecc_curve.decodePoint(c1Bytes);
Cipher cipher = new Cipher();
cipher.Init_dec(userD, c1);
cipher.Decrypt(c2);
cipher.Dofinal(c3);
//返回解密结果
return c2;
}
}
简单就是直接解密
参考第二篇文章直接用就行
M2 sm2 = new SM2(); String s = sm2.simpleDeCode(message, getPrivate_secret());
本文档介绍了如何在Android应用中实现SM2国密算法的解密,基于两个开源代码库进行整合,重点讲解了SM2解密函数的使用和自定义类SM2的实现过程。
1922

被折叠的 条评论
为什么被折叠?



