
在打包Android APK的时候进行签名需要选择一个keystore,查看秘钥库:
C:\Users\47355\.android>keytool -list -v -keystore debug.keystore
输入密钥库口令:
密钥库类型: PKCS12
密钥库提供方: SUN
您的密钥库包含 1 个条目
别名: androiddebugkey
条目类型: PrivateKeyEntry
证书链长度: 1
证书[1]:
所有者: C=US, O=Android, CN=Android Debug
发布者: C=US, O=Android, CN=Android Debug
序列号: 1
生效时间: Mon Mar 07 12:44:02 CST 2022, 失效时间: Wed Feb 28 12:44:02 CST 2052
证书指纹:
SHA1: 5B:AE:41:23:D7:B4:40:DA:70:F2:D7:C6:25:A0:F1:45:6A:23:A8:9E
SHA256: 77:CE:12:A1:9B:FA:5E:40:DD:C1:B7:1B:C4:58:E1:A0:A7:50:D7:DF:2C:87:A5:82:DD:3F:A7:11:77:BB:52:BE
签名算法名称: SHA1withRSA (弱)
主体公共密钥算法: 2048 位 RSA 密钥
版本: 1
Warning:
<androiddebugkey> 使用的 SHA1withRSA 签名算法被视为存在安全风险。此算法将在未来的更新中被禁用。
使用Android studio生成秘钥库:
使用Java的keytool生成秘钥库:
keytool -genkey -alias ali1 -keyalg RSA -keysize 1024 -keystore C:\Users\47355\Desktop\kst\bbb.keystore
使用Java代码生成秘钥库
public static void main(String[] args) throws GeneralSecurityException {
try {
/**
* PKCS12,这是一个标准的密钥库类型,可以在Java和其他语言中使用。
* 您可以在sun.security.pkcs12.PKCS12KeyStore找到这个密钥库的实现。
* 它通常有p12或pfx的扩展。您可以在此类型上存储私钥、密钥和证书。
* 与JKS不同,PKCS12密钥库上的私钥可以用Java提取。
* 这种类型是可移植的,可以与其他语言编写的其他库一起 *** 作,如C、C++或C语言
*/
// KeyStore ks = KeyStore.getInstance("JKS");
// KeyStore ks = KeyStore.getInstance(ANDROID_KEY_STORE);
// KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
// KeyStore ks = KeyStore.getInstance(PKCS12_KEYSTORE_TYPE, BouncyCastleProvider.PROVIDER_NAME);
KeyStore ks = KeyStore.getInstance("pkcs12");
ks.load(null, null);
/**
* 签名算法名称: SHA1withRSA、SHA256withRSA
*/
CertAndKeyGen certAndKeyGen = new CertAndKeyGen("RSA", "SHA1WithRSA", null);
/**
* keySize除了1024还有2048
*/
certAndKeyGen.generate(keysize);
PrivateKey privateKey = certAndKeyGen.getPrivateKey();
PublicKey publicKey = certAndKeyGen.getPublicKey();
X509Certificate[] chain = new X509Certificate[1];
X500Name x500Name = new X500Name(commonName, organizationalUnit, organization, city, state, country);
chain[0] = certAndKeyGen.getSelfCertificate(x500Name, new Date(), (long)validity*24*60*60);
// store away the key store
FileOutputStream fos = new FileOutputStream(filePath);
/**
* 此处只能用privateKey
*/
// ks.setKeyEntry(alias, publicKey, keyPassword, chain);
ks.setKeyEntry(alias, privateKey, keyPassword, chain);
ks.store(fos, keyPassword);
fos.close();
System.out.println("create Success");
} catch (KeyStoreException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (CertificateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Java代码验证签名
static Cipher cipher;
static {
// 使用默认RSA
try {
cipher = Cipher.getInstance("RSA");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
FileInputStream is = new FileInputStream(new File("C:\Users\47355\Desktop\kst\aaa.jks"));
KeyStore keyStore = KeyStore.getInstance("JKS");
keyStore.load(is, "s7865787".toCharArray());
/**
* 别名
*/
Enumeration aliasEnum = keyStore.aliases();
String keyAlias = "" ;
while (aliasEnum.hasMoreElements()) {
keyAlias = (String) aliasEnum.nextElement();
System.out.println("别名"+keyAlias);
}
/**
* 证书指纹
*/
Certificate certificate = keyStore.getCertificate(keyAlias);
X509Certificate x509Certificate = (X509Certificate) certificate;
digest(x509Certificate.getEncoded(),"SHA-1");
/**
*加载公钥
*/
PublicKey publicKey = certificate.getPublicKey();
/**
* 加载私钥,这里填私钥密码
*/
KeyStore.Entry keyStoreEntry = keyStore.getEntry(keyAlias,
new KeyStore.PasswordProtection("s7865787".toCharArray()));
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry) keyStoreEntry;
PrivateKey privateKey = privateKeyEntry.getPrivateKey();
/**
* 加载私钥另一写法
*/
//PrivateKey privateKey = (PrivateKey) keyStore.getKey(keyAlias, "123456".toCharArray());
/**
* base64输出私钥
* Base64是一种用64个字符来表示任意二进制数据的方法。它是一种编码方式,而非加密方式。
* 它通过将二进制数据转变为64个“可打印字符”,完成了数据在HTTP协议上的传输
*/
String strKey = Base64.getEncoder().encodeToString(privateKey.getEncoded());
System.out.println("Base64输出私钥:"+strKey);
/**
* 签名 + 验签 + 编码
*/
// String signBase64Encoded = Base64.getEncoder().encodeToString(sign("测试msg".getBytes(),privateKey,"SHA1withRSA",null));
// boolean verfi = verify("测试msg".getBytes(),Base64.getDecoder().decode(signBase64Encoded), publicKey,"SHA1withRSA",null);
// System.out.println(verfi);
/**
* 签名(私钥加密) + 验签
*/
String message = "我是消息";
byte[] signature = sign(message.getBytes(StandardCharsets.UTF_8), privateKey, "SHA1withRSA", null);
boolean verify = verify(message.getBytes(StandardCharsets.UTF_8), signature,publicKey, "SHA1withRSA", null);
System.out.println("验签结果:"+verify);
/**
* 摘要
*/
// byte[] privateEncrypted = privateEncrypt(message.getBytes(StandardCharsets.UTF_8), privateKey);
byte[] digest = digest(message.getBytes(StandardCharsets.UTF_8), "SHA-1");
/**
* 私钥加密摘要
* 使用Cipher进行私钥加密 r1
* 使用RSACore进行私钥加密 r2
* signature.sign() r3
* 结论:r1、r2、r3三者不相等
*/
byte[] privateEncrypted = privateEncryptWithCipherRSA(digest, privateKey);
byte[] privateEncrypted2 = RSACore.rsa(digest, (RSAPrivateKey)privateKey, true);
/**
* 公钥解密
*/
// publicDecrypted 等于 digest,公钥解密成功
byte[] publicDecrypted = publicDecryptWithCipherRSA((RSAPublicKey) publicKey, privateEncrypted);
/**
* 公钥加密
*/
byte[] publicEncrypted = publicEncrypt(digest, publicKey);
/**
* 私钥解密
*/
final byte[] privateDecrypted = privateDecrypt(privateKey, publicEncrypted);
System.out.println("end");
}
/**
* 公钥解密
*/
public static byte[] publicDecryptWithCipherRSA(RSAPublicKey publicKey, byte[] cipherData)
throws Exception {
Cipher cipher;
try {
// 使用默认RSA
cipher = Cipher.getInstance("RSA");
// cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] output = cipher.doFinal(cipherData);
return output;
} catch (NoSuchAlgorithmException e) {
throw new Exception("无此解密算法");
} catch (NoSuchPaddingException e) {
e.printStackTrace();
return null;
} catch (InvalidKeyException e) {
throw new Exception("解密公钥非法,请检查");
} catch (IllegalBlockSizeException e) {
throw new Exception("密文长度非法");
} catch (BadPaddingException e) {
throw new Exception("密文数据已损坏");
}
}
/**
* 私钥解密
*/
public static byte[] privateDecrypt(PrivateKey privateKey, byte[] cipherData)
throws Exception {
byte[] output = null;
try {
// cipher= Cipher.getInstance("RSA", new BouncyCastleProvider());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
output = cipher.doFinal(cipherData);
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
throw new Exception("密文长度非法");
} catch (BadPaddingException e) {
throw new Exception("密文数据已损坏");
}
return output;
}
/**
* 私钥加密
*/
public static byte[] privateEncryptWithCipherRSA(byte[] messageBytes,PrivateKey privateKey) {
Cipher cipher;
try {
// 使用默认RSA
cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] output = cipher.doFinal(messageBytes);
return output;
} catch (NoSuchAlgorithmException e) {
// 无此加密算法
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
// 加密私钥非法,请检查
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// 明文长度非法
e.printStackTrace();
} catch (BadPaddingException e) {
// 明文数据已损坏
e.printStackTrace();
}
return null;
}
/**
* 公钥加密
*/
public static byte[] publicEncrypt(byte[] messageBytes,PublicKey publicKey) {
try {
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] output = cipher.doFinal(messageBytes);
return output;
} catch (IllegalBlockSizeException | InvalidKeyException e) {
// 明文长度非法
e.printStackTrace();
} catch (BadPaddingException e) {
// 明文数据已损坏
e.printStackTrace();
}
return null;
}
/**
* 计算字节数组指纹
*/
public static byte[] digest(byte[] der,String algorithm) throws NoSuchAlgorithmException, CertificateEncodingException {
/**
* 证书指纹
*/
// MessageDigest md = MessageDigest.getInstance("SHA-1");
// MessageDigest md = MessageDigest.getInstance("md5");
// MessageDigest md = MessageDigest.getInstance("sha-256");
MessageDigest md = MessageDigest.getInstance(algorithm);
md.update(der);
byte[] digest = md.digest();
String digestHex = DatatypeConverter.printHexBinary(digest);
final String s = digestHex.toLowerCase();
return digest;
}
/**
* 签名
*/
public static byte[] sign(byte[] message, PrivateKey privateKey, String algorithm, String provider) throws Exception {
Signature signature;
if (null == provider || provider.length() == 0) {
signature = Signature.getInstance(algorithm);
} else {
signature = Signature.getInstance(algorithm, provider);
}
signature.initSign(privateKey);
signature.update(message);
return signature.sign();
}
/**
* 验签
*/
public static boolean verify(byte[] message, byte[] signMessage, PublicKey publicKey, String algorithm,
String provider) throws Exception {
Signature signature;
if (null == provider || provider.length() == 0) {
signature = Signature.getInstance(algorithm);
} else {
signature = Signature.getInstance(algorithm, provider);
}
signature.initVerify(publicKey);
signature.update(message);
return signature.verify(signMessage);
}
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)