文章出處

     此文章適合于SSIS新手,我是個小白,在繁復查閱資料后仍無果到最后解決問題,走了很多彎路,現在講其中一些關于SSIS的理解寫出來,供大家參考,在正文之前,我就我自己的理解,闡明一些概念。

   什么是SSIS? 大數據中會涉及到一個概念, 叫ETL,中文就是數據的提取、加載、轉換。SSIS是ETL常用工具中的一種,具體的這位仁兄的博客寫的很詳細http://www.cnblogs.com/qinpengming/archive/2011/12/06/2278299.html。我就不過多贅述了

   如果從SSIS包中需要讀取SQL數據庫中的連接信息,當然前提是這些信息是加密過的。需要一個媒介,來進行解密,再將解密后的連接字符串進行賦值,來讓SSIS包正常執行封裝測試。其實思路很明確,但是過程中總是會遇到一些莫名其妙的問題,尤其是在做升級的時候。

關于封裝密碼明文的解決方案如下:

 

  1. 當把包在VS2015中打開之後,點擊SSIS菜單欄下的Package Configuration,查看鏈接管理配置信息。所以如下圖所示

 

 

 

    2.當我們選擇用是腳本來解密數據庫連接字符串的時候,就不再需要用配置包的SQL連接來獲取了,所以需要刪除相關的數據庫配置數據,組態只保留除連接數據庫配置以外的連接信息。因為組態讀取某個數據庫的配置信息,我們會把數據庫里面的數據庫連接加密,下面Connection Managers是識別不了加密的數據庫連接,這樣在VS2015上是可以正常跑,但是數據庫調用會報錯。所以我們要把組態里面的數據庫連接刪除。用腳本去數據庫里面取讀取數據庫連接,并解密,把解密出來的數據庫連接賦值給Connection Managers。

    3.添加一個腳本放在每個Package最前面,然后腳本中先寫一個用windows身份連接的

       

 public static string GetConDb(string filter, string Dbname)
    {
        string Reaconn = "";
        string constr = "Data Source=.;Initial Catalog=IBBC;Integrated Security=SSPI;";
        string sqlstr = "SELECT * FROM IBBC.dbo.Table_1 where temp1='"+filter+"' and  temp2='"+Dbname+"'";
        SqlConnection con = new SqlConnection(constr);
        SqlCommand cmd = new SqlCommand(sqlstr, con);
        con.Open();
        try
        {
            SqlDataReader sdr = cmd.ExecuteReader();
            while (sdr.Read())
            {
                //此處獲取對應的整個sql身份驗證的連接字符串
                string bb = sdr[1].ToString();
                string[] connecstr = bb.Split();
                for (int i = 0; i < connecstr.Length; i++)
                {
                    //判斷是否匹配到數組中的的密碼
                    if (connecstr[i].Contains("Password"))
                    {
                        //獲取帶密碼的字符串長度,比如:Password=Xeferfa0=長度為18
                        int GrossPwdlth = connecstr[i].Length;
                        //獲取Password=后面的加密字符
                        string RevertoldPwd = connecstr[i].Substring(9, GrossPwdlth - 9);
                        //將獲取到的密碼密文進行解密
                        string newpwd = DecryptDES(RevertoldPwd, UUkey);
                        //將密文密碼替換成明文密碼
                        bb = bb.Replace(RevertoldPwd, newpwd);
                    }
                   
                }
                Reaconn = bb;
            }
            return Reaconn;
        }
        catch (Exception ex)
        {

            throw new Exception(ex.Message); ;
        }
        finally 
        {
            con.Close();        
        }      
    }

 

然后再用腳本組件中自帶的DTs對象,將解密后的連接字符串賦值給配置數據源的名字 Dts.Connections[item].ConnectionString = Reaconn; , 當然中間采用什么加密方式,什么解密方式,各位都是大神,初級的也不是很難,我用的Des加密,如下。

    private static byte[] Keys = { 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF };
    //密鑰
    private static string UUkey = "********";
    /**/
    /**/
    /**/
    /// <summary>
    /// DES加密字符串
    /// </summary>
    /// <param name="encryptString">待加密的字符串</param>
    /// <param name="encryptKey">加密密鑰,要求為8位</param>
    /// <returns>加密成功返回加密后的字符串,失敗返回源串</returns>
    public static string EncryptDES(string encryptString, string encryptKey)
    {
        try
        {
            byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0, 8));
            byte[] rgbIV = Keys;
            byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
            DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
            MemoryStream mStream = new MemoryStream();
            CryptoStream cStream = new CryptoStream(mStream, dCSP.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
            cStream.Write(inputByteArray, 0, inputByteArray.Length);
            cStream.FlushFinalBlock();
            return Convert.ToBase64String(mStream.ToArray());


        }
        catch
        {
            return encryptString;
        }
    }
    /**/
    /**/
    /**/
    /// <summary>
    /// DES解密字符串
    /// </summary>
    /// <param name="decryptString">待解密的字符串</param>
    /// <param name="decryptKey">解密密鑰,要求為8位,和加密密鑰相同</param>
    /// <returns>解密成功返回解密后的字符串,失敗返源串</returns>
    public static string DecryptDES(string decryptString, string decryptKey)
    {
        try
        {
            byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey);
            byte[] rgbIV = Keys;
            byte[] inputByteArray = Convert.FromBase64String(decryptString);
            DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
            MemoryStream mStream = new MemoryStream();
            CryptoStream cStream = new CryptoStream(mStream, DCSP.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
            cStream.Write(inputByteArray, 0, inputByteArray.Length);
            cStream.FlushFinalBlock();
            return Encoding.UTF8.GetString(mStream.ToArray());
        }
        catch
        {
            return decryptString;
        }

    }

 

4.到目前為止,所有的代碼工作已經完成,剩下的就是配置問題,當我在VS2015環境中跑包全部通過之后,就只剩下SQL2012上進行封裝跑包,在此期間,需要鼠標點擊整個項目右鍵選中屬性,此時在右側屬性欄位中,在ProtectionLevel 下選擇EncryptSensitiveWithUserKey模式,之前沒選擇該模式,VS中關閉再打開包,連接數據源那里就會報紅,VS和sql跑包都會失敗,sql中提示未正確連接數據庫,這里足足卡殼了兩天,終于找到是這里保護級別的原因,具體內容見下表

 

不保存敏感數據 (DontSaveSensitive)

保存包時不保存包中敏感屬性的值。 這種保護級別不進行加密,但它防止標記為敏感的屬性隨包一起保存,因此其他用戶將無法使用這些敏感數據。 如果其他用戶打開該包,敏感信息將被替換為空白,用戶必須提供這些敏感信息。

當與 dtutil 實用工具 (dtutil.exe) 一起使用時,此保護級別對應的值為 0。

使用密碼加密所有數據 (EncryptAllWithPassword)

使用密碼加密整個包。 使用用戶在創建包或導出包時提供的密碼加密包。 若要在 SSIS 設計器中打開包或使用 dtexec 命令提示實用工具運行包,用戶必須提供包密碼。 如果沒有密碼,用戶將無法訪問或運行包。

當與 dtutil 實用工具一起使用時,此保護級別對應的值為 3。

使用用戶密鑰加密所有數據 (EncryptAllWithUserKey)

使用基于當前用戶配置文件的密鑰加密整個包。 只有創建包或導出包的用戶才可以在 SSIS 設計器中打開包或使用 dtexec 命令提示實用工具運行包。

當與 dtutil 實用工具一起使用時,此保護級別對應的值為 4。

注意

對于使用用戶密鑰的保護級別,Integration Services 使用 DPAPI 標準。 有關 DPAPI 的詳細信息,請參閱位于 http://msdn.microsoft.com/library 的 MSDN Library。

使用密碼加密敏感數據 (EncryptSensitiveWithPassword)

使用密碼只加密包中敏感屬性的值。 DPAPI 用于此加密。 敏感數據作為包的一部分保存,但數據是使用當前用戶在創建包或導出包時提供的密碼加密的。 若要在 SSIS 設計器中打開包,用戶必須提供包密碼。 如果不提供該密碼,則包雖然可以打開但其中不包含敏感數據,當前用戶必須為敏感數據提供新值。 如果用戶試圖在不提供密碼的情況下執行包,則包執行將會失敗。 有關密碼和命令行執行的詳細信息,請參閱dtexec 實用工具

當與 dtutil 實用工具一起使用時,此保護級別對應的值為 2。

使用用戶密鑰加密敏感數據 (EncryptSensitiveWithUserKey)

使用基于當前用戶配置文件的密鑰只加密包中敏感屬性的值。 只有使用同一配置文件的同一個用戶才能加載此包。 如果其他用戶打開該包,敏感信息將被替換為空白,當前用戶必須為敏感數據提供新值。 如果用戶試圖執行該包,則包執行將會失敗。 DPAPI 用于此加密。

當與 dtutil 實用工具一起使用時,此保護級別對應的值為 1。

注意

對于使用用戶密鑰的保護級別,Integration Services 使用 DPAPI 標準。 有關 DPAPI 的詳細信息,請參閱位于 http://msdn.microsoft.com/library 的 MSDN Library。

依靠服務器存儲進行加密 (ServerStorage)

使用 SQL Server 數據庫角色保護整個包。 在將包保存到 SQL Server msdb 數據庫后,支持此選項。 此外,SSISDB 目錄使用 ServerStorage 保護級別。

在將包從 SQL Server Data Tools (SSDT) 保存到文件系統時,不支持此選項。

 

5.設置完后,請把packag關閉,在開啟。看Connection Managers里面的數據庫連接有沒有報紅,如果沒有,就說明設置好了。

6.所有的準備工作都已完成,將包附加到SQL2012 中進行封裝測試,如下圖,包 執行封裝測試成功

 

 

 作為資深小白,記錄第一篇隨筆,留下個腳印

 

-------市人皆大笑,舉手揶揄之

 


 


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()