繁体   English   中英

比较Java中的PublicKey对象

[英]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来比较PublicKeygetAlgorithmgetEncodedgetFormat这样做:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM