{"id":97945,"date":"2018-01-31T07:00:00","date_gmt":"2018-01-31T22:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/?p=97945"},"modified":"2020-06-04T13:06:08","modified_gmt":"2020-06-04T20:06:08","slug":"20180131-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20180131-00\/?p=97945","title":{"rendered":"How can I get a signature for a Windows system that will remain unchanged even if the user reinstalls Windows?"},"content":{"rendered":"<p>The <a href=\"https:\/\/docs.microsoft.com\/en-us\/uwp\/api\/Windows.System.Profile.SystemIdentification\"><code>System\u00adIdentification<\/code> runtime class<\/a> (introduced in the Windows 10 Anniversary Update) gives you a signature for a Windows system that will remain unchanged even if the user reinstalls Windows. There are some caveats, though.<\/p>\n<p>To obtain a value that is consistent across reinstalls of Windows, the method uses the Trusted Platform Module (TPM), or if a TPM is not available, the Unified Extensible Firmware Interface (UEFI). If neither is available, then starting in the Fall Creators Update, the method creates a unique ID and saves it in the registry. The registry value is preserved across upgrades, but is lost if the user performs a clean install of Windows. You can use the <code>Source<\/code> property to determine how the signature was generated.<\/p>\n<p>The value you receive is specific to the publisher specified in your application manifest. If you are a classic Win32 app with no manifest, then the system will use a generic &#8220;publisher&#8221; that is used for all publisher-less apps. Signatures generated for apps with the same publisher will match. Signatures generated for apps with different publishers will not match.<\/p>\n<p>Here&#8217;s some sample code:<\/p>\n<pre>\/\/ JavaScript\r\n\r\nvar buffer = Windows.System.Profile.SystemIdentification.\r\n                                      getSystemIdForPublisher();\r\nvar id  = buffer.id;\r\nvar asHex = Windows.Security.Cryptography.CryptographicBuffer.\r\n                                      encodeToHexString(id);\r\nvar asBase64 = Windows.Security.Cryptography.CryptographicBuffer.\r\n                                      encodeToBase64String(id);\r\n\r\n\/\/ C#\r\n\r\nvar buffer = Windows.System.Profile.SystemIdentification.\r\n                                      GetSystemIdForPublisher();\r\nvar id = buffer.Id;\r\nvar asHex = Windows.Security.Cryptography.CryptographicBuffer.\r\n                                      EncodeToHexString(id);\r\nvar asBase64 = Windows.Security.Cryptography.CryptographicBuffer.\r\n                                      EncodeToBase64String(id);\r\n\r\n\/\/ C++\/CX\r\n\r\nauto buffer = Windows::System::Profile::SystemIdentification::\r\n                                      GetSystemIdForPublisher();\r\nauto id = buffer-&gt;Id;\r\nauto asHex = Windows::Security::Cryptography::CryptographicBuffer::\r\n                                      EncodeToHexString(id);\r\nauto asBase64 = Windows::Security::Cryptography::CryptographicBuffer::\r\n                                      EncodeToBase64String(id);\r\n\/\/ C++\/WinRT\r\n\r\nusing namespace winrt;\r\n\r\nauto buffer = Windows::System::Profile::SystemIdentification::\r\n                                      GetSystemIdForPublisher();\r\nauto id = buffer.Id();\r\nauto asHex = Windows::Security::Cryptography::CryptographicBuffer::\r\n                                      EncodeToHexString(id);\r\nauto asBase64 = Windows::Security::Cryptography::CryptographicBuffer::\r\n                                      EncodeToBase64String(id);\r\n\r\n\/\/ Raw C++ with WRL\r\n\r\nusing namespace ABI::Windows::Storage::Streams;\r\nusing namespace ABI::Windows::System::Profile;\r\nusing namespace Microsoft::WRL;\r\nusing namespace Microsoft::WRL::Wrappers;\r\n\r\nComPtr&lt;ISystemIdentificationStatics&gt; systemIdStatics;\r\nRoGetActivationFactory(HStringReference(\r\n    RuntimeClass_Windows_System_Profile_SystemIdentification).Get(),\r\n    IID_PPV_ARGS(&amp;systemIdStatics));\r\n\r\nComPtr&lt;ISystemIdentificationInfo&gt; info;\r\nsystemIdStatics-&gt;GetSystemIdForPublisher(&amp;info);\r\n\r\nComPtr&lt;IBuffer&gt; id;\r\ninfo-&gt;get_Id(&amp;id);\r\n\r\nComPtr&lt;ICryptographicBufferStatics&gt; cryptoBufferStatics;\r\nRoGetActivationFactory(HStringReference(\r\n    RuntimeClass_Windows_Security_Cryptography_CryptographicBuffer).Get(),\r\n    IID_PPV_ARGS(&amp;cryptoBufferStatics));\r\n\r\nHString asHex;\r\ncryptoBufferStatics-&gt;EncodeToHexString(id.Get(),\r\n                                       asHex.GetAddressOf());\r\n\r\nHString asBase64;\r\ncryptoBufferStatics-&gt;EncodeToBase64String(id.Get(),\r\n                                          asBase64.GetAddressOf());\r\n<\/pre>\n<p>If you want to operate with the raw bytes instead of just encoding them into hex or base64, you can <a href=\"https:\/\/stackoverflow.com\/q\/11853838\/902497\">use the <code>IBufferByteAccess<\/code> interface or the <code>Cryptographic\u00adBuffer.<\/code><code>Copy\u00adTo\u00adByte\u00adArray<\/code> method<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The SystemIdentification class will give you something.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-97945","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The SystemIdentification class will give you something.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/97945","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=97945"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/97945\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=97945"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=97945"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=97945"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}