[英]Compare PublicKey object in java
我有兩個PublicKey對象。我想比較兩者是否相等,或者使用Java安全性API或充氣城堡API檢查哪個是最新對象。
您可以使用equals
if (!key.equals(copyKey)){
System.out.println("not equals!");
}
或檢查鍵的哈希碼
if (key.hashCode() != copyKey.hashCode())
{
System.out.println("public key hashCode check failed");
}
或比較兩個公鑰的十六進制字符串
String encodedKey1 = new String(Hex.encode(key1.getEncoded()));
String encodedKey2 = new String(Hex.encode(key2.getEncoded()));
if (!encodedKey1.equals(encodedKey2)){
System.out.println("not equals!");
}
您可以在Bouncy Castle Tests中進行很多關鍵的比較並檢查示例,請查看org.bouncycastle.jce.provider.test
軟件包中的一些代碼。 BC並非絕對必要,您可以使用默認的Java安全類進行比較。
看一下Oracle的文檔 ,我認為您可以使用它的3個getter來比較PublicKey
: getAlgorithm
, getEncoded
, getFormat
這樣做:
oldKey.getAlgorithm().equals(newKey.getAlgorithm())
等。
通常,使用某種ID對公鑰進行比較。 取決於協議,如何計算密鑰ID。 最好的方法可能是遵守PKCS#11規范,該規范定義了計算密鑰ID的方法。
創建日期不是密鑰本身的組成部分。 您必須在其他地方定義它,或者應該使用公用密鑰容器,例如X509證書。 請注意,您可以使用鍵ID(的十六進制表示)在地圖中查找創建日期。
最好在模數上使用SHA-1哈希作為ID。 公鑰和私鑰的模數相同,並且每個密鑰對的模數應該不同。 以下代碼計算RSA公鑰的ID。
顯然,您始終也可以直接比較兩個鍵的模量。 密鑰ID有點容易存儲。
public class CreateRSAPublicKeyID {
/**
* Creates a key ID for a given key.
*
* @param key the key
* @return the key ID for the given key
*/
public static byte[] createKeyID(Key key) {
if (key instanceof RSAKey) {
RSAKey rsaKey = (RSAKey) key;
BigInteger modulus = rsaKey.getModulus();
if (modulus.bitLength() % Byte.SIZE != 0) {
throw new IllegalArgumentException("This method currently only works with RSA key sizes that are a multiple of 8 in bits");
}
final byte[] modulusData = i2os(modulus, modulus.bitLength() / Byte.SIZE);
MessageDigest sha1;
try {
sha1 = MessageDigest.getInstance("SHA-1");
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("SHA-1 message digest should be available in any Java SE runtime", e);
}
return sha1.digest(modulusData);
}
throw new UnsupportedOperationException("Key type not supported");
}
/**
* Integer to octet string (I2OS) creates a fixed size, left padded, big-endian octet string representation for
* a given integer.
*
* @param i the integer
* @param octets the number of octets (bytes)
* @return the octet string representation of i
*/
public static byte[] i2os(BigInteger i, int octets) {
if (i.bitLength() > octets * Byte.SIZE) {
throw new IllegalArgumentException("i does not fit in " + octets + " octets");
}
final byte[] is = i.toByteArray();
if (is.length == octets) {
return is;
}
final byte[] ius = new byte[octets];
if (is.length == octets + 1) {
System.arraycopy(is, 1, ius, 0, octets);
} else {
System.arraycopy(is, 0, ius, octets - is.length, is.length);
}
return ius;
}
public static String toHex(byte[] data) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.length; i++) {
sb.append(String.format("%02X", data[i]));
}
return sb.toString();
}
public static void main(String[] args) throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair pair = kpg.generateKeyPair();
byte[] keyID = createKeyID(pair.getPublic());
System.out.println(toHex(keyID));
}
}
請注意, getModulus()
命令可能與某些密鑰庫(例如,那些代表HSM令牌或智能卡的密鑰庫getModulus()
不兼容。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.