首先,我不是 Java 程序员。我正在寻找解决此问题的示例,因为我的 Java 开发人员没有太多加密方面的经验。我们在网上找到的所有内容都与加密网页和处理 MS keystore 有关。我们只想使用 PowerBuilder (PB) 中的单个字符串并能够在 Java 中对其进行解密。这里的限制是 MS 库。由于某些限制,我们不得不使用这种加密方法,因此由 Java 端来处理向其抛出的内容。
我有一个 PB 版本 10.2 程序,需要调用此 Java 实用程序并向其传递用户名和密码。我们正在尝试将密码加密为命令行友好的字符串,因为这就是 PB 调用 Java 应用程序的方式。
在 PB 中我使用以下对象: http://www.topwizprogramming.com/freecode_crypto.html
该代码的作用是包装 advapi32.dll 中的 Microsoft 加密 API。它使用的函数有:
CryptAcquireContext http://msdn.microsoft.com/en-us/library/aa379886(VS.85).aspx
CryptCreateHash http://msdn.microsoft.com/en-us/library/aa379908(VS.85).aspx
加密哈希数据 http://msdn.microsoft.com/en-us/library/aa380202(VS.85).aspx
CryptDeriveKey http://msdn.microsoft.com/en-us/library/aa379916(VS.85).aspx
CryptEncrypt http://msdn.microsoft.com/en-us/library/aa379924(VS.85).aspx
它使用 Microsoft Strong Cryptographic Provider 和 PROV_RSA_FULL。该代码获取要加密的数据,将其转换为 BLOB,然后传递给加密函数。在那里,它获取上下文,从上下文创建哈希对象,对密码进行哈希处理,从哈希中获取 session key ,然后调用加密/解密。最后一件事是它获取返回的 BLOB 并将其转换为 ANSI 字符集下的字符串。
有很多常量,乍一看我就明白其中一些来自哪里,而另一些则不太清楚: 常量字符串 KEY_CONTAINER = "MyKeyContainer" 常量 ULong PROV_RSA_FULL = 1 常量 ULong CALG_MD5 = 32771 常量 ULong CALG_RC4 = 26625 常量 ULong ENCRYPT_ALGORITHM = CALG_RC4 常量 ULong CRYPT_NEWKEYSET = 8 常量 ULong ERROR_MORE_DATA = 234
无论是在 1.5 中使用 BouncyCaSTLe 之类的工具还是在 1.6 中使用适用于 MS 的 Sun 加密接口(interface)来完成此操作,我都不在乎,我们只是渴望看到这项工作,而且说实话,这超出了我们的能力范围。
<小时/>嘿,我需要加密一个字符串并将其存储在一个文件中,然后我需要再次读取该文件并解密回相同的字符串。 但我不想加密整个文件。一旦我将所需的加密值存储在文件中,我需要将其单独转换为原始字符串。 您能帮我提供示例代码吗?
最佳答案
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Decrypt
{
public static void main(String... argv)
throws Exception
{
byte[] password = "password".getBytes("UTF-8");
byte[] ciphertext = { -68, -112, 66, 78, 85, 50, 22, -63,
16, 24, -45, 4, -116, -14, 88, 34,
-85, 116, 105, 59, 45, -126 };
byte[] plaintext = decrypt(password, ciphertext);
System.out.println(new String(plaintext, "UTF-8"));
}
public static byte[] decrypt(byte[] password, byte[] ciphertext)
throws GeneralSecurityException
{
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] hash = digest.digest(password);
Cipher rc4 = Cipher.getInstance("RC4");
rc4.init(Cipher.DECRYPT_MODE, new SecretKeySpec(hash, "RC4"));
return rc4.doFinal(ciphertext);
}
}
注意:
这种“加密”太可怕了。 RC4 是 key 流密码。 切勿对多条消息使用相同的 key 流密码!以这种方式对多条消息使用相同的密码,可以轻松恢复纯文本和给定多个密文的 key 。鉴于 MD5 的弱点,他们也可能可以恢复密码。这些缺陷足以危及良好的流密码,但 RC4 与 MD5 一样,也有其自身的漏洞,不建议用于新应用程序。
我确信您知道所有这些,并且受到某些遗留应用程序的限制,但如果其他人看到这个答案,他们需要了解您被迫使用的 PowerBuilder“加密”库的实现不合格。
<小时/>由于密码输入和输出始终是“二进制”,因此当密码文本必须通过面向文本的 channel (如命令行)时,通常使用文本编码,例如 Base-64 或 Base-85。如果可能的话,您可以在调用 Java 实用程序之前对密文进行 Base-64 编码吗?这将使您免受任何字符编码问题的影响。
关于java - 需要一个示例 - 使用 Microsoft Crypto API 解密 Java 中的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/658826/