MessageDigest
创建
MessageDigest sha = MessageDigest.getInstance("SHA-256");
计算i1,i2,i3摘要
sha.update(i1);
sha.update(i2);
sha.update(i3);
byte[] hash = sha.digest();
等价于
sha.update(i1);
sha.update(i2);
byte[] hash = sha.digest(i3);
密钥对生成器
创建
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA");
算法不依赖创建
keyGen.initialize(2048);
SecureRandom random = SecureRandom.getInstance("DRBG", "SUN");
random.setSeed(userSeed);
keyGen.initialize(2048, random);
算法依赖创建
DSAParameterSpec dsaSpec = new DSAParameterSpec(p, q, g);
keyGen.initialize(dsaSpec);
生成密钥对
KeyPair pair = keyGen.generateKeyPair();
签名&验签
生成签名
Signature dsa = Signature.getInstance("SHA256withDSA");
/* Initializing the object with a private key */
PrivateKey priv = pair.getPrivate();
dsa.initSign(priv);
/* Update and sign the data */
dsa.update(data);
byte[] sig = dsa.sign();
验证签名
/* Initializing the object with the public key */
PublicKey pub = pair.getPublic();
dsa.initVerify(pub);
/* Update and verify the data */
dsa.update(data);
boolean verifies = dsa.verify(sig);
System.out.println("signature verifies: " + verifies);
使用KeyFactory和KeySpec签名&验签
签名
DSAPrivateKeySpec dsaPrivKeySpec = new DSAPrivateKeySpec(x, p, q, g);
KeyFactory keyFactory = KeyFactory.getInstance("DSA");
PrivateKey privKey = keyFactory.generatePrivate(dsaPrivKeySpec);
Signature sig = Signature.getInstance("SHA256withDSA");
sig.initSign(privKey);
sig.update(someData);
byte[] signature = sig.sign();
签名后发送给客服方:数据、签名值、公钥;客户方则可以验签;
验签
X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(encodedPubKey);
KeyFactory keyFactory = KeyFactory.getInstance("DSA");
PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
Signature sig = Signature.getInstance("SHA256withDSA");
sig.initVerify(pubKey);
sig.update(data);
sig.verify(signature);
KeyFactory转换KeySpec
DSAPublicKeySpec dsaPubKeySpec =
(DSAPublicKeySpec)keyFactory.getKeySpec(pubKey,
DSAPublicKeySpec.class)
对比key算法相等
static boolean keysEqual(Key key1, Key key2) {
if (key1.equals(key2)) {
return true;
}
if (Arrays.equals(key1.getEncoded(), key2.getEncoded())) {
return true;
}
// More code for different types of keys here.
// For example, the following code can check if
// an RSAPrivateKey and an RSAPrivateCrtKey are equal:
// if ((key1 instanceof RSAPrivateKey) &&
// (key2 instanceof RSAPrivateKey)) {
// if ((key1.getModulus().equals(key2.getModulus())) &&
// (key1.getPrivateExponent().equals(
// key2.getPrivateExponent()))) {
// return true;
// }
// }
return false;
}
证书
读取Base64-Encoded证书
证书格式:
开始于:
-----BEGIN CERTIFICATE-----
结束于:
-----END CERTIFICATE-----
解析
FileInputStream(不支持 markand reset)转换为 a ByteArrayInputStream(支持那些方法),这样每次调用generateCertificate只消耗一个证书,并且输入流的读取位置定位到文件中的下一个证书:
FileInputStream fis = new FileInputStream(filename);
BufferedInputStream bis = new BufferedInputStream(fis);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
while (bis.available() > 0) {
Certificate cert = cf.generateCertificate(bis);
System.out.println(cert.toString());
}
解析证书回复
以下示例解析存储在文件中的 PKCS7 格式的证书回复,并从中提取所有证书:
FileInputStream fis = new FileInputStream(filename);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
Collection c = cf.generateCertificates(fis);
Iterator i = c.iterator();
while (i.hasNext()) {
Certificate cert = (Certificate)i.next();
System.out.println(cert);
}
加密
生成key
我们不指定提供者,因为我们不关心特定的 AES 密钥生成实现。由于我们不初始化 KeyGenerator,系统提供的随机源和默认密钥大小将用于创建 AES 密钥.
生成密钥后,可以重新使用相同的 KeyGenerator 对象来创建更多密钥。
KeyGenerator keygen = KeyGenerator.getInstance("AES");
SecretKey aesKey = keygen.generateKey();
创建Cipher
Cipher aesCipher;
// Create the cipher
aesCipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
加密1AES
// Initialize the cipher for encryption
aesCipher.init(Cipher.ENCRYPT_MODE, aesKey);
// Our cleartext
byte[] cleartext = "This is just an example".getBytes();
// Encrypt the cleartext
byte[] ciphertext = aesCipher.doFinal(cleartext);
// Initialize the same cipher for decryption
aesCipher.init(Cipher.DECRYPT_MODE, aesKey);
// Decrypt the ciphertext
byte[] cleartext1 = aesCipher.doFinal(ciphertext);
加密2 基于密码
PBEKeySpec pbeKeySpec;
PBEParameterSpec pbeParamSpec;
SecretKeyFactory keyFac;
// Salt
byte[] salt = new SecureRandom().nextBytes(salt);
// Iteration count
int count = 1000;
// Create PBE parameter set
pbeParamSpec = new PBEParameterSpec(salt, count);
// Prompt user for encryption password.
// Collect user password as char array, and convert
// it into a SecretKey object, using a PBE key
// factory.
char[] password = System.console.readPassword("Enter encryption password: ");
pbeKeySpec = new PBEKeySpec(password);
keyFac = SecretKeyFactory.getInstance("PBEWithHmacSHA256AndAES_256");
SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
// Create PBE Cipher
Cipher pbeCipher = Cipher.getInstance("PBEWithHmacSHA256AndAES_256");
// Initialize PBE Cipher with key and parameters
pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);
// Our cleartext
byte[] cleartext = "This is another example".getBytes();
// Encrypt the cleartext
byte[] ciphertext = pbeCipher.doFinal(cleartext);
参考
https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html#Examples