我们正在将数据从旧版 Java 应用程序迁移到较新的 .NET 应用程序中。Java 应用程序有一个 MySQL 后端,而 .NET 应用程序有一个 SQL Server 后端。我们拥有两者的完整源代码和配置文件,但没有一个开发 Java 应用程序的开发人员仍在公司,我们不得不对一些逻辑进行逆向工程以迁移数据。在我们的测试中,我们的大部分数据都正确移动。但是有一列的加密值我们遇到了麻烦。
据我所知,Java 应用程序中没有显式调用任何方法来在访问列时对其进行加密或解密。相反,加密似乎是在用于访问数据(休眠)的 ORM 内部自动发生的。我找到了一个名为的 XML 文件/entities/TABLENAME.hbm.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
-method 加密进行加密,使用密码PASSWORD
和SALTSALTSALTSALTSALTSALTSALTSALTSALT
. 那么,问题是如何解密 .NET 中的列值?
到目前为止,我最好的领导是Tom Hundley 发布的这个PKCSKeyGenerator 类。使用它,我在 .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 中的参数,但我没有取得任何进展。我似乎无法使这个描述起作用。你有什么建议吗?提前致谢。