我正在尝试创建一个可以使用 OpenSSL 发送签名和加密邮件的 android 应用程序。
到目前为止,我能够发送签名电子邮件并使用 Web 浏览器和我的 Android 应用程序验证它们。
加密和解密也是如此。
但是现在当我尝试从我的 android 应用程序发送签名+加密的邮件时。Exchange 服务器无法验证/解密从我的 android 应用程序发送的邮件。
当我尝试使用 OWA 打开这些邮件时,我收到此错误:
One or more errors occurred while the message was being loaded. Error: (0x800ccef6)
The digital signature of this message couldn't be validated because an error occurred while the message was being loaded.
关于这个错误代码意味着什么的任何指针?
更新 1:-添加加密和签名代码。
签名代码:
public static boolean Java_PKCS7Sign(File inputFile, File outputFile, PrivateKey privateKey, X509Certificate certificate, String signingAlgorithm) {
try {
String inputFilePath = inputFile.getAbsolutePath();
String outputFilePath = outputFile.getAbsolutePath();
byte arr[] = android.security.Credentials.convertToPem(certificate);
InputStream certIs = new ByteArrayInputStream(arr);
OpenSSLX509Certificate openSSLcert = OpenSSLX509Certificate.fromX509PemInputStream(certIs);
byte openSSLcertEncoded[] = openSSLcert.getEncoded();
long signCertRef = NativeCrypto.d2i_X509(openSSLcertEncoded);
OpenSSLKey oKey = OpenSSLKey.fromPrivateKey(privateKey);
long evpKeyRef = oKey.getPkeyContext();
//boolean res = PKCS7Sign(signCertRef, pkeyRef, certs, bioRef, flags, a, b)
long arr1[] = new long[0];
return PKCS7Sign(inputFilePath, signCertRef, evpKeyRef, arr1, outputFilePath);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
上面的代码PKCS7Sign
是对 OpenSSL 的 JNI 调用。用于签名的标志是:int flgs = PKCS7_STREAM | PKCS7_DETACHED | PKCS7_BINARY ;
加密代码:
public static boolean Java_PKCS7encrypt(File inputData, File output, X509Certificate[] recipientCertificates, String encryptionAlgorithm) {
if(!inputData.exists() || !output.exists())
return false;
try {
fis = new FileInputStream(inputData);
OpenSSLBIOInputStream bis = new OpenSSLBIOInputStream(fis);
long bioRef = NativeCrypto.create_BIO_InputStream(bis);
int certsRefArrLength = recipientCertificates.length;
long certsRefArr[] = new long[certsRefArrLength];
for (int i = 0; i < certsRefArrLength; i++) {
byte arr[] = android.security.Credentials.convertToPem(recipientCertificates[i]);
InputStream certIs = new ByteArrayInputStream(arr);
OpenSSLX509Certificate openSSLcert = OpenSSLX509Certificate.fromX509PemInputStream(certIs);
byte openSSLcertEncoded[] = openSSLcert.getEncoded();
certsRefArr[i] = NativeCrypto.d2i_X509(openSSLcertEncoded);
}
String outputFilePath = output.getAbsolutePath();
return PKCS7encrypt(bioRef, certsRefArr, outputFilePath, encryptionAlgorithm);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (CertificateEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
与符号相同的PKCS7encrypt
是对 OpenSSL 的 JNI 调用。使用的标志是:
int flags = PKCS7_STREAM | PKCS7_BINARY;
用于加密的密码是cipher = EVP_rc2_40_cbc();