我們正在將遺留Java應用程序的數據遷移到我們新的.NET應用程序中。 Java應用程序有一個MySQL後端,.NET應用程序有一個SQL Server後端。我們有兩個完整的源代碼和配置文件,但沒有一個從事Java應用程序的開發人員仍然在公司工作,我們不得不逆向工程來遷移一些數據。我們的大部分數據在我們的測試中正常移動。但是有一列加密值,我們遇到了麻煩。在.NET中,如何解密使用Java中的PBEWithMD5AndDES加密的值?
據我所知,Java應用程序中沒有顯式調用任何方法來在訪問列時加密或解密列。相反,加密似乎是在用於訪問數據的ORM中自動發生的(Hibernate)。我找到了一個名爲/entities/TABLENAME.hbm.xml
的XML文件,我相信它是該列的Hibernate模型定義。是XML文件中的相關線路如下:
<property name="columnname" type="stringEncrypted">
<column name="TBL_COLUMNNAME" not-null="false" unique="false" sql-type="VARCHAR(255)"/>
</property>
注意,類型爲stringEncrypted
。爲stringEncrypted
的定義似乎是/entities/global/User.hbm.xml
,如下:
<typedef name="stringEncrypted" class="org.jasypt.hibernate.type.EncryptedStringType">
<param name="encryptorRegisteredName">stringEncrypter</param>
</typedef>
然後是stringEncrypter
設置似乎是在/webapp/resources/spring/CompanyName-encryption.xml
如下(消毒,當然):
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="stringEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor">
<property name="password">
<value>PASSWORD</value>
</property>
<property name="algorithm">
<value>PBEWithMD5AndDES</value>
</property>
<property name="saltGenerator">
<ref bean="fixedStringSaltGenerator"/>
</property>
</bean>
<bean id="fixedStringSaltGenerator" class="org.jasypt.salt.FixedStringSaltGenerator">
<property name="salt">
<value>SALTSALTSALTSALTSALTSALTSALTSALTSALT</value>
</property>
</bean>
<bean id="hibernateEncryptor" class="org.jasypt.hibernate.encryptor.HibernatePBEStringEncryptor">
<property name="registeredName">
<value>stringEncrypter</value>
</property>
<property name="encryptor">
<ref bean="stringEncryptor" />
</property>
</bean>
</beans>
所以,我想想這告訴我,該列是否使用PBEWithMD5AndDES
-方法加密進行加密,使用的密碼爲PASSWORD
,鹽的編號爲SALTSALTSALTSALTSALTSALTSALTSALTSALT
。所以,問題是如何解密.NET中的列值?
目前爲止我的最愛是這張PKCSKeyGenerator class由Tom Hundley發佈。利用這一點,我已經嘗試在.NET中的以下內容:
string encryptedInput = "mG5bz6duwBL3jVCLKyI8Zw=="; // This is an encrypted value copied from MySQL Workbench
string saltString = "SALTSALTSALTSALTSALTSALTSALTSALTSALT";
string keyString = "PASSWORD";
byte[] saltBytes = new byte[saltString.Length * sizeof(char)];
System.Buffer.BlockCopy(saltString.ToCharArray(), 0, saltBytes, 0, saltBytes.Length);
PKCSKeyGenerator crypto = new PKCSKeyGenerator(
keyString, // key
saltBytes, // salt
13, 1); // Magic numbers. I don't really get 'em.
ICryptoTransform ct = crypto.Decryptor;
byte[] cipherBytes = Convert.FromBase64String(encryptedInput);
byte[] clearBytes = ct.TransformFinalBlock(cipherBytes, 0, cipherBytes.Length);
string clearString = Encoding.Unicode.GetString(clearBytes);
當我跑,我得到:
CryptographicException: Bad Data
我環顧四周,其他解密方法,掃描的Java代碼任何其他可能正在使用的代碼,並且使用PKCSKeyGenerator中的參數進行修飾,並且我沒有取得任何進展。我似乎無法使這個解鎖工作。你有什麼建議嗎?提前致謝。
DES不安全,並且Java PBEWithMD5andDES算法不遵循PKCS#5標準。而不是嘗試在.NET中重新創建當前的加密過程,是否可以修改數據庫?然後,您可以使用Java代碼來解密當前字段,並使用更容易在.NET中支持的體面算法對它們進行重新加密。 – erickson
@erickson - 目標是將數據永久解密。我們很滿意任何可以實現這一目標的方法。我們試着用Java解密數據,但是我們很難讓舊的Java代碼編譯和運行,因爲我們現在使用的是完全不同的技術棧,而不是編寫應用程序。我們可以繼續嘗試,但我希望在.NET中解密數據要比試圖恢復Java代碼更容易。 –