Adding a Certificate to Trusted Publishers using Microsoft Intune
Published Dec 10 2020 09:15 AM 48.7K Views

By Jason Sandys – Sr. Program Manager | Microsoft Intune

 

Two significant actions on Windows devices require code-signing using a trusted, code-signing certificate:

 

In the case of third-party application updates, the tool used to inject the updates into the WSUS catalog signs the updates using a code-signing certificate that you provide. This signing is strictly required and enforced by Windows.

 

You must manually sign PowerShell scripts; this is also strictly required and enforced by Windows if the system's execution policy mandates this. See about signing in the PowerShell documentation for more details on script signing and the execution policy. See Hey, Scripting Guy! How Can I Sign Windows PowerShell Scripts with an Enterprise Windows PKI? for a detailed step-by-step of signing a script.

 

In addition to Windows trusting the code-signing certificate used to sign third-party application updates and PowerShell scripts, the certificate must also exist in the Trusted Publishers certificate store on systems installing the third-party update or running the PowerShell script. Adding a certificate to the Trusted Publishers store for a Windows device using Intune is straight forward but involves a few steps as outlined below.

 

Note: That the Base-64 string value cannot include extra formatting characters, such as embedded linefeeds (see RootCATrustedCertificates CSP for more information). Remove linefeeds by searching for “\r\b” and replace them with an empty string.

 

What's needed

You need the following three items to add a certificate to the Trusted Publishers store using Intune.

  • The code-signing certificate you wish to add.
  • The base-64 encoded version of the code-signing certificate.
  • The thumbprint of the code-signing certificate.

 

You don't need the private key for the certificate. You only need the private key when signing a file including scripts and third-party updates.

 

The code-signing certificate

If you don't have a copy of the code-signing certificate, you can extract it from a file previously signed by the certificate using the following steps:

  1. Right-click on the signed file and choose Properties.

  2. Choose the Digital Signatures tab. If this tab does not appear, then the file is not signed.

  3. Choose the appropriate signature from the Signatures list and then select Details. Most files will only have a single signature.

  4. In the Digital Signature Details dialog, choose View Certificate.

  5. In the Certificate dialog, choose the Details tab and select Copy to File.

  6. Complete the Certificate Export Wizard to create a CER file containing the certificate. Choose Base-64 encoded x.509 (.CER) for the Export File Format.

  7. Select OK on the three open dialogs.

    Code-signing certificate dialog boxes on a Windows device.Code-signing certificate dialog boxes on a Windows device.

 

Thumbprint of the certificate

A certificate's thumbprint is a dynamically computed identifier that uniquely distinguishes it from other certificates. You can retrieve the thumbprint of a certificate in various ways, including the following:

  1. From the properties of the certificate. You can do this for either a certificate stored in a file (like the .CER file extracted above) or a certificate stored in the Windows certificate store:
    1. Open the certificate by double-clicking the file or the certificate's entry in the MMC Certificates snap-in. You can also right-click on the certificate and choose Open from the context menu.
    2. On the Details tab, scroll down to and select the Thumbprint item in the list box.
    3. Copy the thumbprint from the details pane in the dialog.
    4. Press OK to close the open Certificate dialog.
  2. Using PowerShell:
    1. For a certificate stored in a file (like the .CER file extracted above):
      ([System.Security.Cryptography.X509Certificates.X509Certificate2]::new("<path_to_certificate>")).thumbprint​

      PowerShell terminal displaying the thumbprint of certs stored in a file.PowerShell terminal displaying the thumbprint of certs stored in a file.
    2. For a certificate stored in your Personal certificate store:
      Get-ChildItem -Path Cert:\CurrentUser\My | Format-Lis​t

      PowerShell terminal displaying the thumbprint of certs stored in a Personal certificate store.PowerShell terminal displaying the thumbprint of certs stored in a Personal certificate store.

Base-64 encoded version of the certificate

The base-64 encoded version of a certificate is a string-based representation of the certificate. This version contains the complete certificate but in a more portable format that is not bound to a file. Similar to the thumbprint, you can obtain the base-64 encoded version of a certificate in several ways, including the following:

  1. From a base-64 encoded .CER file (like the .CER file extracted above):
    1. Open the created .CER file with Notepad.
    2. Copy the lines between -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----.

      Note: The Base-64 string value cannot include extra formatting characters, such as embedded linefeeds (see RootCATrustedCertificates CSP for more information). Remove linefeeds by searching for “\r\b” and replace them with an empty string.

    3. Close Notepad.
  2. Using PowerShell:
    1. For a certificate stored in your Personal certificate store:
      [System.Convert]::ToBase64String((Get-Item -Path Cert:\CurrentUser\My\<thumbprint>).RawData, 'InsertLineBreaks')​

      PowerShell terminal displaying the thumbprint of Base-64 certs stored in a Personal certificate store.PowerShell terminal displaying the thumbprint of Base-64 certs stored in a Personal certificate store.
    2. For a certificate stored in a .CER file:
      [System.Convert]::ToBase64String(([System.Security.Cryptography.X509Certificates.X509Certificate2]::new("<path_to_certificate>")).Export('Cert'), 'InsertLineBreaks')​

      PowerShell terminal displaying the thumbprint of Base-64 certs stored in a .CER file.PowerShell terminal displaying the thumbprint of Base-64 certs stored in a .CER file.

The Step-By-Step Guide

To add a certificate to the Trusted Publishers store using Intune, use a custom profile and an OMA-URI to apply a setting from the RootCATrustedCertificates CSP.

 

  1. Follow the instructions at Create a profile with custom settings in Intune to create a new, custom, Windows 10 device configuration profile.
  2. Use the following values for the fields in the custom profile:
    1. Name: The name of the certificate.
    2. OMA-URI: ./Device/Vendor/MSFT/RootCATrustedCertificates/TrustedPublisher/<thumbprint>/EncodedCertificate
    3. Data type: String
    4. Value: The base-64 encoded version of the certificate without any line breaks.

      Note: The Base-64 string value cannot include extra formatting characters, such as embedded linefeeds (see RootCATrustedCertificates CSP for more information). Remove linefeeds by searching for “\r\b” and replace them with an empty string.



      Intune - OMA-URI policy settings.Intune - OMA-URI policy settings.

  3. Add scope tags and assignments as necessary.

 

Additional Notes

  • Windows systems should already trust certificates issued by a public CA. When using a certificate from an alternate source for any purpose, including those listed in this article, you need to add the root certificates for the PKI that issued the certificate to your managed Windows devices. See Create trusted certificate profiles in Microsoft Intune for steps to do this using Intune.
  • Through the magic of Authenticode, a signature is still valid even if the code-signing certificate used to sign a file is past its expiration date. As long as the certificate was valid when it was used to sign a file, then the expiration of the certificate itself does not impact the validity of the signature.
  • Driver and Windows update installation also require signing using a trusted code-signing certificate, however, either Microsoft or the hardware vendor that creates and supplies the associated files signs them. Administrators do not have to add any certificates to the Trusted Publishers store and no additional action is necessary to install either of these.
  • If you're not signing your PowerShell scripts and configuring an execution policy to require signing of PowerShell scripts, you should strongly reconsider your practices as this is a very important safety measure (more on this in a follow-up post).
  • You can also use certutil.exe for all of the operations above. Official documentation on certutil.exe is sparse, though, so this is left as an exercise for the reader if desired.

 

Let us know if you have any additional questions on this by replying back to this post below or tagging @JasonSandys or @IntuneSuppTeam out on Twitter.

 

Post updates:

03/14/22: PowerShell formatting fix to include a parenthesis. Thanks for the feedback!

01/09/23: Added note about removing extra formatting characters for the RootCATrustedCertificates CSP. Thanks for the feedback!

32 Comments
Iron Contributor

Hi Jason,

Much appreciated post, thanks for documenting and formalizing this process!

When I tested this same approach I noticed that the base-64 encoded version of the certificate (the really long value between -----BEGIN CERTIFICATE----- and -----END CERTIFICATE-----) seems to only work if it does not contain any linefeeds etc. Using a tool like Notepad+ these can easily be removed by searching for '\r\b' and replacing it with an empty string ''.

The CSP documentation mentions this ('The Base-64 string value cannot include extra formatting characters such as embedded linefeeds, etc. '), but it might be useful to call this out to make sure people don't trip over that.

Regards,

Jan

Microsoft

Hi Jan. Thank you for the comment. You are 100% correct and I've slightly adjusted the post above to reflect this. Thank you.

Brass Contributor

This works as designed, however the reporting in Intune gives some errors.

 

This happens in multiple tenants. any idea what causes this?

 

EncodedCertificate [./Device/Vendor/MSFT/RootCaTrustedCertificates/TrustedPublisher/<thumbprint>/EncodedCertificate]

STATE
Error
ERROR CODE
0x87d1fde8
ERROR DETAILS
Remediation failed

Hi Jason,

 

Looks like something went wrong with the command to retrieve the Bae64 from a cer file. I believe the opening bracket is missing.

I believe the new method is something added in later .Net versions, so that could be another challenge.

This command did work for me:

[System.Convert]::ToBase64String(([System.Security.Cryptography.X509Certificates.X509Certificate2]::CreateFromCertFile("<path_to_certificate>")).Export('Cert'), 'InsertLineBreaks')

 

Best,

Kim

 

Hi @kim oppalfens, the post has been updated with the missing bracket. Thanks for the feedback!

Steel Contributor

Just like @Sander de Wit , I am also experiencing error 0x87d1fde8 (Remediation Failed). However, the policy is getting applied successfully. Is this a known issue with this particular CSP @JasonSandys or @IntuneSuppTeam?

Copper Contributor

I see the same thing as @rahuljindal-MVP where I pushed it, I see it successfully drop the cert on the machine but on Intune it says Remediation Failed with error code 0x87d1fde8.

Brass Contributor

Nice article thanks!

 

Is there a way to trust *all* code signing certificated my enterprise CA has created (we have one per user so we know who edited last signed file).

In the current case I am signing all my PowerShell scripts used for scheduled tasks. They are stored in sysvol and thus considered untrusted.

I signed the PowerShell script with a users code-signing cert.  The scheduled tasks are run by NTAUTHORITY\SYSTEM,

 

I tried adding the CA cert via GPO to the trusted publishers machine store and that doesn't seem to have worked and generates a 'rejected by administrator' alert in task scheduler.

 

Logging on as domain admin to the machine where the task is to run and manually running the PowerShell script results in the untrusted publisher notification and asking me if i want to trust it.

 

Do I really have to add every code signing cert in the enterprise to trusted publishers? 

Microsoft

Hi @alexbal,

 

I'm assuming you are wanting to have all of the certs added as trusted publishers and not just trusted (as there is a difference). For this, no, there is no way to do this except individually. Adding the cert from the root CA that issued these certs to the trusted publishers store has no effect. Thus, yes, you must add each individual cert used for code-signing to the trusted publisher store. With group policy, this is pretty easy and with the above method, it's also pretty quick in Intune. With a little bit of effort, the above can also be fully automated using the Graph API to create the profile and run against multiple certs with minimal manual effort.

Copper Contributor

@Jason_Sandys thanks for confirming the as-designed behavior, i will stop banging my head against that wall.  This is for a small home lab so i can do that easily (there is only me!). (oops this is alexbal, wasn't paying attention to which account i was using)

 

However it occurred to me that in an IT pro shop when scripts change a lot, by many individuals, one would have to implement a secrets vault and make signing hard to use the one long lived cert and if the cert was compromised or more likely an admin went rogue one has to re-sign everything.

 

If one could issue per-admin code signing certs then just the rogue admin's certs could be revoked.  But for this to be feasible from a management perspective one wouldn't want to distribute potentially hundreds of certs - especially for machines nor domain joined.... (i only learnt about the intune cert connector today, and have no clue how that would work on say, linux).  Was just a thought, can't help being a PM :)

 

Copper Contributor

I have the same issue ...

 

I see the same thing as @rahuljindal where I pushed it, I see it successfully drop the cert on the machine but on Intune it says Remediation Failed with error code 0x87d1fde8.

Copper Contributor

I also got the error message.

 

But the certificate is sucessfull applied to the user certificate store.

 

ERROR CODE = 0x87d1fde8
State Details = -2016281112 (Remediation failed)
Copper Contributor

Same Remediation failed issue here..

Any updates on this  @Intune_Support_Team  ?

 

Need to deploy a certificate to 500+ devices and not looking forward to all the errors in our Intune Dashboard. I guess there isn't some kind of way to acknowledge or suppress these?

 

Brass Contributor

Folks,

the remediation error as mentioned by others above is "an issue by design".

 

I had a support ticket open with MS and it took a bit of time but eventually MS got back to me to say they had the same result in their lab and it's been reported to the back end team to investigate.

 

So long as the cert actually appears on the local computer> trusted publishers store then move on.

 

Might be fixed down the track... maybe.

Iron Contributor

Hello Jason_Sandys,

first of all, thanks for the great post.
Exactly what I'm searching for. :)

 

Maybee one question to clarify the need for this.
You mentioned there should be 2 main cases where you need code-signing certificates.

Am I missing something or should there be a third big case, where you need it - Microsoft Office Macro-Code-Signing?

Or am I missing some better way for archiving this?

 

Thanks.

Microsoft

Hi @SeMeDe.

 

Thank you. As for the additional use case of signing Office/M365 Apps macros, yes, I think that is certainly valid. Those are just scripts ultimately and for security and validation purposes, they should be signed as well. This does also mean that the cert used to sign them must be trusted and a trusted publisher. More info on signing M365 Apps macros can be found at Digitally sign your macro project (microsoft.com).

Brass Contributor

Hi there Jason ,

are you able to confirm that the remediation error seen when deploying via Intune as you've described is indeed expected?

 

-2016281112 (Remediation failed)

 

ERROR CODE
0x87d1fde8
ERROR DETAILS
Remediation failed
 
Thanks,
Shane.

 

Microsoft

Hi @shane_foley

 

Unfortunately, at this time, this does appear to be a confirmed issue in at least some versions of Windows (the issue is with how the CSP itself reports its status back). Of course, in my lab, I didn't experience this issue at all so at best, there is at least some inconsistency.

Brass Contributor

Hi there Jason - thanks for getting back to me.

 

The CSP DDF file would suggest there are additional OMA strings required, eg;

 

<Node> <NodeName>EncodedCertificate</NodeName> <DFProperties> <AccessType> <Add /> <Get /> <Replace /> </AccessType> <Description>Specifies the X.509 certificate as a Base64-encoded string. The Base-64 string value cannot include extra formatting characters such as embedded linefeeds, etc.</Description> <DFFormat> <b64 /> </DFFormat> <Occurrence> <One /> </Occurrence> <Scope> <Dynamic /> </Scope> <CaseSense> <CIS /> </CaseSense> <DFType> <DDFName></DDFName> </DFType> </DFProperties> </Node>

 

RootCATrustedCertificates DDF file - Windows Client Management | Microsoft Docs

 

Is it worth looking at expanding the string out using the DDF?

 

Thanks,

Shane.

Copper Contributor

@Jason_Sandys unfortunately, the issue still persists. Two years after @Sander de Wit reported this, it is still there. Do you have an update, please? We are about to deploy this policy to 8.000 (and later to 15.000) devices so it would help if the problem would be solved. Thanks!

Microsoft

Hi @Marco_Dijkshoorn. At this time, there are no further updates as this is still an item being evaluated to be addressed.

Brass Contributor

I've been unsuccessful in getting this to work. I just keep getting a deployment error, and the certificate is not installed on my test device. I am unclear by what this means in your post above, "When using a certificate from an alternate source for any purpose, including those listed in this article, you need to add the root certificates for the PKI that issued the certificate to your managed Windows devices."

 

I added my code-signing certificate to the Trusted Root Certification Authorities store, but I am not sure that's what the above line means. Intune did successfully deploy the certificate in this case, but it will not deploy it to the Trusted Publishers store. 

 

I am also not sure I'm fully understanding the comment about removing line breaks. How do I verify that there are no line breaks or something wrong with my base64 formatting that might be interfering with a successful deployment of my cert?

Brass Contributor

Well, naturally, after posting the above reply it has assigned it to my test device. I'm still receiving an error in the Intune portal, but that appears to be a bug per your previous replies.

Iron Contributor

I have written a script which does all this automatically. You only have to select the certificate and the rest what is necessary to create a configuration profile is done by my script.

Adding a Certificate to Trusted Publishers using Intune – Modern Device Management (jannikreinhard.c...

Copper Contributor

All the folks that are seeing the error remediation, make sure you remove the line breaks from the Base-64 version of the value. Try pasting it in Notepad++ or Word or something. Once those line breaks are removed, copy paste it in the value on Intune and Intune will no longer show "error remediation".

Brass Contributor

@Zeddoo I did this but it still throws and error. I pasted it into Notepad as well as Sublime Text. Still throws an error, but deploys certificate properly.

Copper Contributor

@ahelton_kcl That's odd. I was seeing this for the past year until I came across this guide https://www.inthecloud247.com/add-a-certificate-to-the-trusted-publishers-with-intune-without-report.... I made the changes and it fixed immediately on my end. Any chance you have more than 1 certs being pushed and that one of those still have the line breaks? Try following the guide I just posted.

Brass Contributor

@Zeddoo I was wrong. Just took forever to update in the Intune portal. Free and clear of errors now. Thanks for the tip!

Copper Contributor

Adding trusted publisher certs is handy for silent install of software that contains drivers. Can deploy the certs before the software. Here is a few lines of powershell to create a text file with information need to create the config. Works without error.

 

$cert = (get-item .\DriverCert.cer).FullName
$cert >> cert.txt
$thumbprint = ([System.Security.Cryptography.X509Certificates.X509Certificate2]::new($cert)).thumbprint 
"./Device/Vendor/MSFT/RootCATrustedCertificates/TrustedPublisher/$thumbprint/EncodedCertificate" >> cert.txt
[System.Convert]::ToBase64String(([System.Security.Cryptography.X509Certificates.X509Certificate2]::new($cert)).Export('Cert')) >> cert.txt
Copper Contributor

I changed [System.Convert]::ToBase64String((Get-Item -Path Cert:\CurrentUser\My\<thumbprint>).RawData, 'InsertLineBreaks') to [System.Convert]::ToBase64String((Get-Item -Path Cert:\CurrentUser\My\<thumbprint>).RawData) and imported it, now instead of erroring out I'm getting success.

Copper Contributor

Got remediation error like everyone else at first so just one question.

 

Why does it say to insert line breakers when the string is suppose to be without line breaks? it just adds extra steps to first add them and then remove them.

 

[System.Convert]::ToBase64String(([System.Security.Cryptography.X509Certificates.X509Certificate2]::new("<path_to_certificate>")).Export('Cert'), 'InsertLineBreaks')

Value: The base-64 encoded version of the certificate without any line breaks.

 

Used this and it worked perfectly

[System.Convert]::ToBase64String(([System.Security.Cryptography.X509Certificates.X509Certificate2]::new("<CertPath>")).Export('Cert')) | Set-Clipboard

Copper Contributor

Thank you for sharing this guide. It worked perfectly.

 

Also, I do believe @JoakimJarl is correct, as I also removed 'InsertLineBreaks' and this worked for me without error or the need for removing the linefeeds later. I did not use the Set-Clipboard command though so I will add this handy tip for the next time. Thank you for this reply as well

 

Version history
Last update:
‎Nov 30 2023 04:16 PM
Updated by: