3

I'm trying to find some documentation about using Google's Cloud HSM to sign executables. I have found a quite comprehensive guide for AWS CloudHSM but AWS pricing (>$1,000/month) seems to be orders of magnitude more expensive for our use-case.

Can I apply the AWS guide (above) to Google's Cloud HSM infrastructure or are there any significant differences that I should be aware of?

DaveJ
  • 2,357
  • 6
  • 28
  • 35
  • 1
    You may also want to check out [SignService](https://github.com/onovotny/SignService) which works with [Azure KeyVault](https://azure.microsoft.com/en-us/services/key-vault/). – jariq Feb 02 '19 at 16:17
  • 1
    Cloud HSM integrates into Cloud KMS. Use the Cloud KMS documentation for using keys to sign data. For general information, AWS HSM is good information but you will want to stick with Google documentation for Cloud HSM and Cloud KMS. https://cloud.google.com/kms/docs/digital-signatures - can you clarify your intended purpose for code signing. Your signatures will not be recognized by third parties. For that purpose you will need a certificate backed by a CA. – John Hanley Feb 02 '19 at 19:39
  • @jariq: Thanks for the tip. Do you have experience with the service? – DaveJ Feb 03 '19 at 11:43
  • @JohnHanley: I'm looking to sign an Electron Windows application. I already have an EV cert from Digicert. – DaveJ Feb 03 '19 at 11:45
  • @DaveJ I'm personally signing with local smartcard but SignService is being actively used by majority of [.NET Foundation projects](https://dotnetfoundation.org/Projects) so I guess it should be pretty OK. – jariq Feb 03 '19 at 11:58
  • @jariq: Does the Sign Service have to be on the same subnet as Azure KeyVault or can the service be located anywhere? – DaveJ Feb 03 '19 at 13:07
  • Dave - Having an EV cert does not give you the ability to sign code. You need a code signing certificate. Certificates have "purpose". EV certificates do not have sign. The issue is if you want your signing to be accepted by other software / organizations (validation). If you don't you can just use your own self signed OpenSSL code. If you do need validation, then you will need a signing certificate issued by a CA. – John Hanley Feb 03 '19 at 20:37
  • @JohnHanley: Thanks, it is an EV Code Signing cert from Digicert, I'm currently successfully using it with a USB dongle to sign applications but looking to move over to HSM which Digicert support: https://www.digicert.com/code-signing/ev-code-signing/ – DaveJ Feb 04 '19 at 11:34
  • DaveJ - you cannot use HSM for your Digicert keys as you cannot import keys. https://cloud.google.com/kms/docs/faq#import_keys – John Hanley Feb 04 '19 at 19:23
  • @JohnHanley: Ah ok, I didn't know that. That would rule out Google CloudHSM so. It seems that AWS CloudHSM and Azure KeyVault support importing keys, perhaps Azure is the way go. Is there any reason why Azure KeyVault wouldn't work? – DaveJ Feb 05 '19 at 10:43
  • @JohnHanley You can import keys now. https://cloud.google.com/kms/docs/faq#import_keys – sivabudh Mar 16 '20 at 10:52
  • @sivabudh - thank you for the update. – John Hanley Mar 16 '20 at 16:31

3 Answers3

1

For Windows executables signing (Authenticode) you can use jsign which supports Google Cloud HSM and works on Windows or Linux (as it is a pure Java tool).

Yaegor
  • 1,771
  • 9
  • 12
0

Depending on your project and restrictions you may be able to use java's org.bouncycaslte for the code signing operations.

There is a very helpful pdf for bouncycastle: https://www.bouncycastle.org/fips-java/BCFipsIn100.pdf

Depending on how you are signing the executables the ContentSigner.java provides private key API signing

public class ContentSignerFactory {

    public static ContentSigner getContentSigner(Function<ByteArrayOutputStream, byte[]> lambda, String algorithm) {
        return new ContentSigner() {
            //This is to ensure that signature is created using the right data.
            ByteArrayOutputStream stream = new ByteArrayOutputStream();

            @Override
            public byte[] getSignature() {
                //Calling HSM here instead, the stream is the AttributeMap
                byte[] data = lambda.apply(stream);
                return data;
            }

            //Perhaps called by BouncyCastle library to provide the content
            @Override
            public OutputStream getOutputStream() {
                return stream;
            }

            @Override
            public AlgorithmIdentifier getAlgorithmIdentifier() {
                return new DefaultSignatureAlgorithmIdentifierFinder().find(algorithm);
            }
        };
    }
}

Also AWS HSM is $28000 per year as they require clustered HSM's in order to allow custom KMS store

jmwilkosz
  • 11
  • 1
  • 5
  • This won't be suitable to sign a Windows executable. A dedicated tool like Jsign is required https://ebourg.github.io/jsign/ – Emmanuel Bourg Mar 29 '23 at 07:49
0

At my work we do this (and, for some technical reasons, we use all three cloud vendors' KMS offerings). We have a dedicated signing server that proxies the KMS systems and routes to the appropriate KMS (i.e., AWS, Google, or Azure) based on the key we are trying to use. We also have cryptographic service providers (e.g., KSP for Windows, JCE for Java, CTK for macOS, PKCS11/OpenSSL Engine for Linux, etc.) that send the hash to sign to the signing server which then offloads it to KMS. Bottom line, it all works with the same signing tools we normally use (e.g., signtool, jarsigner, codesign, etc.) and we're able to sign in sub-second time due to the client-side hashing. Another nice byproduct is that we're able to derive our permissions to keys from our Active Directory group memberships since that is all handled at the signing server proxy.

Hmmmmm
  • 778
  • 9
  • 20