java - 需要一个示例 - 使用 Microsoft Crypto API 解密 Java 中的字符串

标签 java encryption cryptography mscapi

首先,我不是 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/

相关文章:

java - 创建 Spring boot Web 服务而不使用 main 方法

python - 解密单字节 XOR 编码文件

c# - 我应该为表中的密码字段使用什么? MD5 还是 SHA1?

java - 我的回归并没有停止执行

java - 创建最终调用指定方法的java方法列表

javascript - 足够安全,可以使用 javascript 进行加密和解密

c++ - 是否可以在 C++ 中的音频文件上应用 RC5 算法?

math - 导致 MD5 冲突的最短字符串对是什么?

c# - 在没有 System.Security.Cryptography 的情况下计算 SHA256 哈希

java - 如何更新 session 属性