【发布时间】:2019-04-09 13:31:04
【问题描述】:
我正在调试一个应用程序,发现它使用了在 .ACF 文件的“Db”字段中加密的数据库连接字符串。虽然我想出了如何编写解密/加密例程,但我无法写回我的新值。
示例 PowerShell 代码片段:
Add-Type -Path C:\app\adodb.dll
Add-Type -TypeDefinition $decryptCode
$recordSet = New-Object ADODB.RecordsetClass
$recordSet.Open("c:\app\connectionstring.acf",[Type]::Missing,[ADODB.CursorTypeEnum]::adOpenKeySet,[ADODB.LockTypeEnum]::adLockBatchOptimistic)
$dbEncrypted = $recordSet.Fields["Db"].Value
"Current Connection String: $([Decryptor.NativeMethods]::Decrypt($dbEncrypted))"
# update connection string
$newConnectionString = "<blah blah blah>"
$recordSet.Fields["Db"].Value = [Decryptor.NativeMethods]::Encrypt($newConnectionString)
$recordSet.Save()
此代码读取连接字符串并对其进行解密。 IT 还可以很好地加密新的连接字符串。但是,当尝试更新“Db”字段时,它会引发错误:
异常设置“Value”:“多步操作产生错误。 检查每个状态值。”在 C:\debugging\Decryptor.ps1:329 char:1 + $recordSet.Fields["Db"].Value = [Decryptor.NativeMethods]::Encrypt($n ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : 未指定: (:) [], SetValueInvocationException + FullyQualifiedErrorId : ExceptionWhenSetting
[Decryptor.NativeMethods]::Encrypt 返回一个字符串,虽然不是所有字符都是可打印的,而且字符串比原始字符串长。
我可以将数据库值设置为普通字符串,或者我刚刚从数据库中读取的字符串:
$recordSet.Fields["Db"].Value = $dbEncrypted
我认为它可能是大小,因为原始加密字符串是 147 个字符,但新的加密字符串是 179 个字符。所以我将新字符串削减为 147 个字符,甚至更少,但它仍然不会设置。所以我怀疑这是由于字符串的内容。
我尝试设置的字符串如下所示:
£àöÌóÓàù:Ò¡J·DμÕ1R|SÀgÐqíÀZ(Lá2 !¯'B$Rä!kýÈg\ISX êmh®¾ oÔçþOZißlß%¼ù@ ÕeæB¦ëvpâNÉ oSÆ!fZÆÿ²ÔFôó Ûvºä2øg ¹¼
àU¸ÏAß0g§ÿ¨brÁƾ('îÙ2ÿééµHãhû=¿ 6Å=#´ú½¬ö
$recordSet 显示以下值:
Properties : {IAccessor, IChapteredRowset, IColumnsInfo, IColumnsRowset...}
AbsolutePosition : 1
ActiveConnection :
BOF : False
Bookmark : 1
CacheSize : 1
CursorType : adOpenStatic
EOF : False
Fields : {DB}
LockType : adLockBatchOptimistic
MaxRecords : 0
RecordCount : 5
Source : c:\app\connectionstring.acf
AbsolutePage : 1
EditMode : adEditNone
Filter : 0
PageCount : 1
PageSize : 10
Sort :
Status : 8
State : 1
CursorLocation : adUseClient
MarshalOptions : adMarshalAll
DataSource : ADODB.RecordsetClass
ActiveCommand :
StayInSync : True
DataMember :
Index :
recordset.Fields["db"] 的当前设置显示:
$recordSet.Fields["Db"]
Status : 0
ActualSize : 147
Attributes : 4
DataFormat :
DefinedSize : 255
Name : DB
NumericScale : 0
OriginalValue :
Precision : 0
Properties : {BASECOLUMNNAME, BASETABLENAME, BASECATALOGNAME, BASESCHEMANAME...}
Type : adVarChar
UnderlyingValue :
Value : £àöÌóÓà™ù:Ò¡J·DµÕ1R|SÀgÐqíÀZ(Lá2 !¯'B$Rä\!kýȘg\ISX ê‰mh®¾ oÔçþOZißlß%¼ù€@Š˜ ÕeæB¦ëvpâNÉ
oSÆ!fZ–Æÿ²ÔFôó Ûvºä2øÀü"ëöÑ@Õ k§«üdÊ'Ó‹Û§1j©
$recordSet.Fields["Db"].Properties 包含
Attributes Name Type Value
---------- ---- ---- -----
1 BASECOLUMNNAME adVarWChar
1 BASETABLENAME adVarWChar
1 BASECATALOGNAME adVarWChar
1 BASESCHEMANAME adVarWChar
1 KEYCOLUMN adBoolean False
1 ISAUTOINCREMENT adBoolean False
1 RELATIONCONDITIONS adVarBinary
1 CALCULATIONINFO adVarBinary
1 OPTIMIZE adBoolean False
在使用不同字符串的进一步测试中发现此字符串有效:
$recordSet.Fields["Db"].Value = "£àöÌóÓà"
但是这个字符串不起作用:
$recordSet.Fields["Db"].Value = "£àöÌóÓà"
Exception setting "Value": "Multiple-step operation generated errors. Check each status value."
At line:1 char:1
+ $recordSet.Fields["Db"].Value = "£àöÌóÓà"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : ExceptionWhenSetting
进一步测试确定以下内容:
$broken = "£àöÌóÓà"
$working = "£àöÌóÓà"
# $broken.Length = 9
# $working.Length = 7
[System.Text.UTF8Encoding]::UTF8.GetBytes($working)
194
163
195
160
195
182
195
140
195
179
195
147
195
160
[System.Text.UTF8Encoding]::UTF8.GetBytes($broken)
194
163
195
160
195
182
195
140
195
179
195
147
195
160
194
129
194
153
【问题讨论】:
标签: .net powershell adodb