如何使用tpmek加密和解密

omjgkv6w  于 2021-06-29  发布在  Java
关注(0)|答案(0)|浏览(313)

我使用的是微软提供的tpm java库。模拟器的连接正在工作。陷入了如何使用tpm endrosment公钥加密字符串和使用tpm endrosment私钥解密。
下面是代码,这是不正确的功能,其中tpm私人ek是不可见的外部世界,然后如何解密使用私人ek。

public class Sample {

    boolean usesTbs;
    Tpm tpm;
    Cipher cipher;
    public static byte[] nullVec = new byte[36];
    private static final String SHA_256 = "SHA-256";
    private static final String EQUALS = "=";
    private final String registrationId;

    private TPMT_PUBLIC ekPublic = null;
    private TPMT_PUBLIC srkPublic = null;
    private TPM2B_PUBLIC idKeyPub = null;

    private static final TPM_HANDLE SRK_PERSISTENT_HANDLE = TPM_HANDLE.persistent(0x00000001);
    private static final TPM_HANDLE EK_PERSISTENT_HANDLE = TPM_HANDLE.persistent(0x00010001);
    private static final TPM_HANDLE ID_KEY_PERSISTENT_HANDLE = TPM_HANDLE.persistent(0x00000100);
    private static final TPMT_SYM_DEF_OBJECT AES_128_SYM_DEF = new TPMT_SYM_DEF_OBJECT(TPM_ALG_ID.AES, 128, TPM_ALG_ID.CFB);

    private static final TPMT_PUBLIC EK_TEMPLATE = new TPMT_PUBLIC(
            // TPMI_ALG_HASH    nameAlg
            TPM_ALG_ID.SHA256,
            // TPMA_OBJECT  objectAttributes
            new TPMA_OBJECT(TPMA_OBJECT.restricted, TPMA_OBJECT.decrypt, TPMA_OBJECT.fixedTPM, TPMA_OBJECT.fixedParent,
                    TPMA_OBJECT.adminWithPolicy, TPMA_OBJECT.sensitiveDataOrigin),
            // TPM2B_DIGEST authPolicy
            javax.xml.bind.DatatypeConverter.parseHexBinary("837197674484b3f81a90cc8d46a5d724fd52d76e06520b64f2a1da1b331469aa"),
            // TPMU_PUBLIC_PARMS    parameters
            new TPMS_RSA_PARMS(AES_128_SYM_DEF, new TPMS_NULL_ASYM_SCHEME(), 2048, 0),
            // TPMU_PUBLIC_ID       unique
            new TPM2B_PUBLIC_KEY_RSA());

    private static final TPMT_PUBLIC SRK_TEMPLATE = new TPMT_PUBLIC(
            // TPMI_ALG_HASH    nameAlg
            TPM_ALG_ID.SHA256,
            // TPMA_OBJECT  objectAttributes
            new TPMA_OBJECT(TPMA_OBJECT.restricted, TPMA_OBJECT.decrypt, TPMA_OBJECT.fixedTPM, TPMA_OBJECT.fixedParent,
                    TPMA_OBJECT.noDA, TPMA_OBJECT.userWithAuth, TPMA_OBJECT.sensitiveDataOrigin),
            // TPM2B_DIGEST authPolicy
            new byte[0],
            // TPMU_PUBLIC_PARMS    parameters
            new TPMS_RSA_PARMS(AES_128_SYM_DEF, new TPMS_NULL_ASYM_SCHEME(), 2048, 0),
            // TPMU_PUBLIC_ID       unique
            new TPM2B_PUBLIC_KEY_RSA());

    public TpmSample() throws Exception {
        System.out.println("===> PATH = " + System.getenv("PATH"));
        System.out.println("===> path = " + System.getenv("path"));

        usesTbs = CmdLine.isOptionPresent("tbs", "t");
        System.out.println("Connecting to " + (usesTbs ? "OS TPM" : "TPM Simulator"));
        tpm = usesTbs ? TpmFactory.platformTpm() : TpmFactory.localTpmSimulator();

        clearPersistent(tpm, EK_PERSISTENT_HANDLE, "EK");
        clearPersistent(tpm, SRK_PERSISTENT_HANDLE, "SRK");
        ekPublic = createPersistentPrimary(tpm, EK_PERSISTENT_HANDLE, TPM_RH.OWNER, EK_TEMPLATE, "EK");
        srkPublic = createPersistentPrimary(tpm, SRK_PERSISTENT_HANDLE, TPM_RH.OWNER, SRK_TEMPLATE, "SRK");
        //SRS_SecurityProviderTPMEmulator_25_002: [ The constructor shall set the registration Id to null if none was provided. ]
        this.registrationId = null;
    }

    private void cleanSlots(TPM_HT slotType) {
        GetCapabilityResponse caps = tpm.GetCapability(TPM_CAP.HANDLES, slotType.toInt() << 24, 8);
        TPML_HANDLE handles = (TPML_HANDLE) caps.capabilityData;

        if (handles.handle.length == 0)
            System.out.println("No dangling " + slotType.name() + " handles");
        else
            for (TPM_HANDLE h : handles.handle) {
                System.out.printf("Dangling " + slotType.name() + " handle 0x%08X\n", h.handle);
                tpm.FlushContext(h);
            }
    }

    public byte[] getEndrosmentPrivateKey() {
        return (new TPM2B_PRIVATE()).toTpm();
    }

    public byte[] getEndorsementKey() {
        //SRS_SecurityProviderTPMEmulator_25_032: [ This method shall return the TPM2B_PUBLIC form of EK. ]
        return (new TPM2B_PUBLIC(ekPublic)).toTpm();
    }

    public byte[] getStorageRootKey() {
        //SRS_SecurityProviderTPMEmulator_25_033: [ This method shall return the TPM2B_PUBLIC form of SRK. ]
        return (new TPM2B_PUBLIC(srkPublic)).toTpm();
    }

    private TPMT_PUBLIC createPersistentPrimary(Tpm tpm, TPM_HANDLE hPersistent, TPM_RH hierarchy, TPMT_PUBLIC inPub, String primaryRole) throws Exception {
        ReadPublicResponse rpResp = tpm._allowErrors().ReadPublic(hPersistent);
        if (rpResp == null) {
            throw new Exception("ReadPublicResponse cannot be null");
        }
        TPM_RC rc = tpm._getLastResponseCode();

        if (rc == TPM_RC.SUCCESS) {
            // TODO: Check if the public area of the existing key matches the requested one
            return rpResp.outPublic;
        }
        if (rc != TPM_RC.HANDLE) {
            throw new Exception("Unexpected failure {" + rc.name() + "} of TPM2_ReadPublic for {" + primaryRole + "}");
        }

        TPMS_SENSITIVE_CREATE sens = new TPMS_SENSITIVE_CREATE(new byte[0], new byte[0]);
        CreatePrimaryResponse cpResp = tpm.CreatePrimary(TPM_HANDLE.from(hierarchy), sens, inPub,
                new byte[0], new TPMS_PCR_SELECTION[0]);
//        System.out.println("RSA Primary Key: \n" + cpResp.toString());
        if (cpResp == null) {
            throw new Exception("CreatePrimaryResponse cannot be null");
        }

        tpm.EvictControl(TPM_HANDLE.from(TPM_RH.OWNER), cpResp.handle, hPersistent);
        tpm.FlushContext(cpResp.handle);
        return cpResp.outPublic;
    }

    private void clearPersistent(Tpm tpm, TPM_HANDLE hPersistent, String keyRole) throws Exception {
        tpm._allowErrors().ReadPublic(hPersistent);
        TPM_RC rc = tpm._getLastResponseCode();
        if (rc == TPM_RC.SUCCESS) {
            tpm.EvictControl(TPM_HANDLE.from(TPM_RH.OWNER), hPersistent, hPersistent);
        } else if (rc != TPM_RC.HANDLE) {
            throw new Exception("Unexpected failure for {" + rc.name() + "} of TPM2_ReadPublic for " + keyRole + " 0x" + hPersistent.handle);
        }
    }

    public SecretKeySpec setKey(byte[] key) {

        MessageDigest digest = null;
        try {
            digest = MessageDigest.getInstance(SHA_256);
            key = digest.digest(key);
            key = Arrays.copyOf(key, 16);
            return new SecretKeySpec(key, "AES");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }

    public byte[] encrypt(String data, byte[] publicEKey) throws Exception {
        SecretKeySpec secretKeySpec = setKey(publicEKey);
        cipher = Cipher.getInstance("AES/CFB/NoPadding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, new IvParameterSpec(new byte[16]));
        byte[] cipherText = cipher.doFinal(data.getBytes("UTF-8"));
        System.out.println("Encrypted Data from Method:->" + new String(cipherText, "UTF-8"));
        return cipherText;
    }

    public byte[] decrypt(byte[] cipherText, byte[] privateEKey) throws Exception {
        SecretKeySpec secretKeySpec = setKey(privateEKey);
        Cipher cipherDecrypt = Cipher.getInstance("AES/CFB/NoPadding");
        cipherDecrypt.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(new byte[16]));
        byte[] decipheredText = cipher.doFinal(cipherText);
        System.out.println("Decrypted Data from Method:-> " + new String(decipheredText));
        return decipheredText;
    }

    public static void main(String[] args) throws Exception {
        String data = "asdfqwert";
        Sample tpmSample = new Sample();
        tpmSample.cleanSlots(TPM_HT.TRANSIENT);
        tpmSample.cleanSlots(TPM_HT.LOADED_SESSION);
        tpmSample.getTpmInformation();
        System.out.println("Endrosment Key :->" + new String(org.bouncycastle.util.encoders.Base64.encode(tpmSample.getEndorsementKey())));
        System.out.println("Private Endrosment Key :->" + new String(org.bouncycastle.util.encoders.Base64.encode(tpmSample.getEndrosmentPrivateKey())));

        byte[] publicEKey = new String(Base64.encode(tpmSample.getEndorsementKey())).getBytes("UTF-8");
        byte[] privateEKey = new String(Base64.encode(tpmSample.getEndrosmentPrivateKey())).getBytes("UTF-8");

        System.out.println("Original Data ->" + data);
        byte[] enc = tpmSample.encrypt(data, publicEKey);
        tpmSample.decrypt(enc, privateEKey);
    }
}

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题