We need to migrate a TDE-encrypted database from one Azure SQL Managed Instance to another Azure SQL Managed Instance. The standard TDE certificate export process (BACKUP CERTIFICATE) doesn't work on Managed Instance. Is there any supported method to expo

Vansh Jain 0 Reputation points
2025-07-09T18:33:45.5233333+00:00

We need to migrate a TDE-encrypted database from one Azure SQL Managed Instance to another Azure SQL Managed Instance. The standard TDE certificate export process (BACKUP CERTIFICATE) doesn't work on Managed Instance. Is there any supported method to export/import TDE certificates between Managed Instances, or do we need to use Azure Database Migration Service?"

Is TDE certificate export possible between Managed Instances?

  1. Are there any undocumented commands or procedures?
  2. Can Azure Database Migration Service handle this scenario?
  3. Is there a way to extract certificates through Azure PowerShell?
  4. What's the official Microsoft recommendation for this scenario
SQL Server Migration Assistant
SQL Server Migration Assistant
A Microsoft tool designed to automate database migration to SQL Server from Access, DB2, MySQL, Oracle, and SAP ASE.
569 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. Erland Sommarskog 122K Reputation points MVP Volunteer Moderator
    2025-07-09T21:41:48.59+00:00

    I have not tried, but I would expect it to be possible to do BACKUP CERTIFICATE to blob store. Nevermind that it can be a bit of a hassle to get the permissions right.

    There is however another alternative, as you can create a certificate from binary strings.

    Here is an example, which shows how to copy a certificate from one database to another. Also, this is a certificate which is protected by a password, not by the database master key.

    DECLARE @public_key varbinary(MAX) =
                certencoded(cert_id('DemoServerCert')),
            @private_key varbinary(MAX) =
                certprivatekey(cert_id('DemoServerCert'),
                               N'Nic nie boli, tak jak życie',
                               N'Nic nie boli, tak jak życie')
    -- Change database.
    USE PermTest
    -- Alas, this syntax is not valid - the binary values must be literal.
    CREATE CERTIFICATE DemoServerCert
    FROM BINARY = @public_key
    WITH PRIVATE KEY
       (BINARY = @private_key,
        DECRYPTION BY PASSWORD = N'Nic nie boli, tak jak życie',
        ENCRYPTION BY PASSWORD = N'Nic nie boli, tak jak życie')
    go
    -- We need to use dynamic SQL, sigh.
    USE master
    go
    DECLARE @public_key varbinary(MAX) =
                certencoded(cert_id('DemoServerCert')),
            @private_key varbinary(MAX) =
                certprivatekey(cert_id('DemoServerCert'),
                               N'Nic nie boli, tak jak życie',
                               N'Nic nie boli, tak jak życie'),
            @sql nvarchar(MAX)
    
    -- Add SELECT so if the SQL comes out blank, you can see which key you did not retrieve.
    --SELECT @public_key, @private_key
    
    SELECT @sql =
       N'CREATE CERTIFICATE DemoServerCert
         FROM BINARY = ' + convert(nvarchar(MAX), @public_key, 1) + N'
         WITH PRIVATE KEY
             (BINARY = ' + convert(nvarchar(MAX), @private_key, 1) + N',
              DECRYPTION BY PASSWORD = N''Nic nie boli, tak jak życie'',
              ENCRYPTION BY PASSWORD = N''Nic nie boli, tak jak życie'')'
    
    PRINT  @sql
    -- Execute the batch in PermTest
    EXEC PermTest..sp_executesql @sql
    
    
    

    Since you are going to copy between instances, you are probably better off to read the hex strings into a PowerShell script.

    Note that when you read the private key into a hex string, you still need a password, to protect it inside that hex string.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.