Android开发人员说如下关于在项目中存储应用程序公钥:
安全建议:强烈建议您不要对Google Play提供的确切公共许可证密钥字符串值进行硬编码.相反,您可以在运行时从子字符串构造整个公共许可证密钥字符串,或者在将其传递给构造函数之前从加密存储中检索它.这种方法使恶意第三方更难以修改APK文件中的公共许可证密钥字符串.
这应该是不言自明的吗?我不明白他们要我做什么.
他们在这个例子的评论中说了同样的话,但他们实际上并没有通过他们的指示来证明他们的意思.这就是它所说的:
不是仅将整个文字字符串存储在*程序中,而是在运行时从片段构造键或使用位操作(例如,使用其他字符串的XOR)来隐藏*实际键.密钥本身不是秘密信息,但我们并不希望攻击者能够轻松地用自己的一个*替换公钥,然后从服务器替换伪造的消息.
那么一个人究竟怎么做到这一点呢?
我有一个1024位的私钥,并用它来生成一个公钥.这是否自动意味着我的公钥也有1024加密?或者它的加密大小可以更小?(512,256 ......)
PS:我最感兴趣的是RSA密钥中模数("n")的大小.大小通常为1024或2048位.但我很高兴看到这引发了一场讨论,所有这些都促进了我对密码学的兴趣.
encryption cryptography bit public-key-encryption private-key
我有一个系统,需要在javascript中生成RSA密钥对,然后将公钥存储在服务器端的数据库中(作为字符串),然后Java中的服务器端将使用存储的公共加密字符串密钥并将其发送到客户端,客户端将使用私钥解密字符串.
我在客户端浏览器上使用了一个browsified版本的node-rsa.
首先在客户端我生成一个密钥对并导出密钥,将它们存储为字符串
var NodeRSA = require('node-rsa');
var key = new NodeRSA({b: 1024});
key.exportKey("pkcs8-private");
key.exportKey("pkcs8-public-pem");
Run Code Online (Sandbox Code Playgroud)
导出的私钥存储在客户端,公共服务器存储在公共服务器上
接下来,我使用java来加密接收到的公钥的字符串,因此我将pkcs8公钥解析为Java PublicKey对象.
String pubKey = "<Retrieved pkcs8 public key>";
pubKey = pubKey.replaceAll("(-+BEGIN PUBLIC KEY-+\\r?\\n|-+END PUBLIC KEY-+\\r?\\n?)", "");
byte[] keyBytes = Base64.decodeBase64(pubKey);
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
PublicKey pk = kf.generatePublic(spec);
Run Code Online (Sandbox Code Playgroud)
并用它加密文本
byte[] cipherText;
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pk);
cipherText = cipher.doFinal("Hello World!".getBytes());
return Base64.encodeBase64String(cipherText);
Run Code Online (Sandbox Code Playgroud)
这很好用,并返回一个像这样的Base64编码加密字符串
WTS1J2f4w5icsUOCtulyHDaBmB5lN7D8mnj0QWMDBkUGiPHkM8nHVx9pd0MtbQAQNasQS2X8kisLMYyEMPasFZtDH0zX1e8lNYaW0xMKsg++ge87f+95nl+TmxDy6S1m7Ce/n0wXno+0MbSv8YsJtsUcAleyyfQX2bxqX8u7Gjs=
Run Code Online (Sandbox Code Playgroud)
然后我尝试在客户端解密它的字符串
首先,我重新导入node-rsa中存储的密钥
var NodeRSA = require('node-rsa');
var key = new NodeRSA();
key.importKey("<exported private …Run Code Online (Sandbox Code Playgroud) 我正在开发一个Node应用程序,我已经在其中构建了一个解密器函数,并使用Openpgp.js npm模块来完成这项工作.我接受了用我们的公钥制作的各种提交的PGP客户端文件,当他们进来时使用我们的私钥解密它们,并将解密的版本放在一个文件夹供我访问,所有看起来都很好....因为文件是装甲的.以下是显示事件顺序的代码示例行:
const encryptedData = fs.readFileSync(encryptedFilePath, 'utf8')
openpgp.decrypt({
message: openpgp.message.readArmored(encryptedData),
publicKeys,
privateKey
}).then( (decrypted) => { fs.writeFile(decryptedFilePath, decrypted.data } )
Run Code Online (Sandbox Code Playgroud)
当装甲文件通过时,一切都很顺利,我在指定的文件夹中获取解密文件.在文本编辑器中打开时,这些文件的格式如下:
-----BEGIN PGP MESSAGE-----
WBh2X7KwfEBDx0LEE1FzlnvxZs44o62FclpTazJpcl9J7DjwVfg9cHCID0TAN6Y6
B3b5bCQQFe1wTgpIkVtd0mFGQx7KGHj4FGte53qseVxC2bfq9PGKRIAUg6olr+82
Run Code Online (Sandbox Code Playgroud)
但是,我们有客户端使用装甲选项关闭加密文件,因此在文本编辑器中打开时它们会以十六进制格式出现....
7403 436d e6c0 f941 daac 945b 9a81 f066
6cd2 0032 5df0 9ca2 23a0 6eec a7bb f24c
a941 99a8 1053 ae23 f88b 245c f709 c2b2
Run Code Online (Sandbox Code Playgroud)
.....或编码文本文件,如下所示:
DµÉ‰í+?3K€Ð?˜PªeZ_|Ò®ó0??ãZqRµ3!ŒpuÉW?NZrìÚk´
Aˆ›œiêø8?Ú?ól:äΟ”?6‡)
w?¬ÌŒWÝÚ¢?Q??œ?œ??H¨¿?œ//?ÃBA?´>(%°?e?
Run Code Online (Sandbox Code Playgroud)
(最后两个类似于我在代码示例中控制日志"encryptedData"时所看到的内容.)
每当有任何非装甲文件进入时,该过程都会失败,我最初会遇到几个不同的错误,具体取决于上面显示的类型.我在fs.readFileSync上删除了'utf8'编码,并将"fromBinary"替换为"readArmored"以将数据作为可能有效的二进制思想处理,但随后我收到有关"无效的解密会话密钥"的错误.所以我尝试在主解密之前使用"decryptSessionKey"函数,因为它在文档中显示,这让我得到一个未定义的密钥和一个关于"没有找到对称加密的会话密钥包"的错误.此外,我可能正在咆哮错误的树,因为使用Openpgp.js的二进制文件似乎需要一个密码,我认为这不同于解锁我的私钥的密码,这是我唯一的密码.
我已经搜索了整个Openpgp.js文档和谷歌搜索疯狂,但似乎无法找到一个可靠的程序,如何修改我的代码,适用于ASCII装甲文件解密非装甲文件.(但是,当使用像PGP桌面这样的桌面解密程序时,每个进来的文件都会快速解密并且没有错误,所以我无法弄清楚我的差异在哪里以及为什么解决方案不明显.)任何人都有任何经验有这个或可能的解决方案?
我试图解决与如何使用RSA加密数据完全相同的用例,SHA-256作为哈希函数,MGF1作为掩码生成函数?,但我需要更清楚一点.
上述查询是在2013年提出的.当时OpenSSL仅支持SHAEP填充的SHA1哈希(硬编码).在最新的OpenSSL(1.0.2k)中,我可以看到使用以下API解决了这个问题:
int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
const unsigned char *from, int flen,
const unsigned char *param, int plen,
const EVP_MD *md, const EVP_MD mgf1md)
Run Code Online (Sandbox Code Playgroud)
RSA_public_encrypt()不将EVP_MD结构作为参数我不知道如何指定它.
如何RSA_public_encrypt()使用掩码生成功能调用SHA-256模式?
我有一种从.cer文件生成公钥的方法。我将.cer文件内容转换为输入流,一旦获得该流,就调用此方法生成公共密钥
public static void generatePublicKey(InputStream inputStream) {
try {
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509", "BC");
Certificate certificate = certificateFactory.generateCertificate(inputStream);
publicKey = certificate.getPublicKey();
inputStream.close();
} catch (CertificateException | IOException e) {
e.printStackTrace();
}
}
Run Code Online (Sandbox Code Playgroud)
它一直有效,直到我们将项目更新为针对Android Pie为止。看起来Google已使用BC提供程序弃用了,这就是造成此问题的原因。如果在getInstance()中使用“ BC”,则会得到NoSuchAlgorithmException。如果我删除“BC”,并通过CertificateFactory.getInstance("X.509")这是由谷歌提出的方法在这里https://android-developers.googleblog.com/2018/03/cryptography-changes-in-android-p.html
我得到
com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: com.android.org.conscrypt.OpenSSLX509CertificateFactory$ParsingException: java.lang.RuntimeException: error:0c0000be:ASN.1 encoding routines:OPENSSL_internal:WRONG_TAG
java android ssl-certificate public-key-encryption x509certificate
我在C中编写一个例程,用公钥读取base64字符串并继续加密字符串.我也测试相同的字符串的解密,但我在尝试解码时收到错误0x0407106B:
$ openssl errstr 0x0407106B
error:0407106B:rsa routines:RSA_padding_check_PKCS1_type_2:block type is not 02
Run Code Online (Sandbox Code Playgroud)
这是代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <openssl/rsa.h>
#include <openssl/engine.h>
//#define PADDING RSA_PKCS1_OAEP_PADDING
#define PADDING RSA_PKCS1_PADDING
//#define PADDING RSA_NO_PADDING
main() {
// public key
char *b64_pKey = "-----BEGIN PUBLIC KEY-----\nMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCp2w+8HUdECo8V5yuKYrWJmUbL\ntD6nSyVifN543axXvNSFzQfWNOGVkMsCo6W4hpl5eHv1p9Hqdcf/ZYQDWCK726u6\nhsZA81AblAOOXKaUaxvFC+ZKRJf+MtUGnv0v7CrGoblm1mMC/OQI1JfSsYi68Epn\naOLepTZw+GLTnusQgwIDAQAB\n-----END PUBLIC KEY-----\n";
// private key
char *b64priv_key = "-----BEGIN RSA PRIVATE KEY-----\nMIICXAIBAAKBgQCp2w+8HUdECo8V5yuKYrWJmUbLtD6nSyVifN543axXvNSFzQfW\nNOGVkMsCo6W4hpl5eHv1p9Hqdcf/ZYQDWCK726u6hsZA81AblAOOXKaUaxvFC+ZK\nRJf+MtUGnv0v7CrGoblm1mMC/OQI1JfSsYi68EpnaOLepTZw+GLTnusQgwIDAQAB\nAoGBAKDuq3PikblH/9YS11AgwjwC++7ZcltzeZJdGTSPY1El2n6Dip9ML0hUjeSM\nROIWtac/nsNcJCnvOnUjK/c3NIAaGJcfRPiH/S0Ga6ROiDfFj2UXAmk/v4wRRUzr\n5lsA0jgEt5qcq2Xr/JPQVGB4wUgL/yQK0dDhW0EdrJ707e3BAkEA1aIHbmcVfCP8\nY/uWuK0lvWxrIWfR5MlHhI8tD9lvkot2kyXiV+jB6/gktwk1QaFsy7dCXn7w03+k\nxrjEGGN+kQJBAMuKf55lDtU9K2Js3YSStTZAXP+Hz7XpoLxmbWFyGvBx806WjgAD\n624irwS+0tBxkERbRcisfb2cXmAx8earT9MCQDZuVCpjBWxd1t66qYpgQ29iAmG+\njBIY3qn9uOOC6RSTiCCx1FvFqDMxRFmGdRVFxeyZwsVE3qNksF0Zko0MPKECQCEe\noDV97DP2iCCz5je0R5hUUM2jo8DOC0GcyR+aGZgWcqjPBrwp5x08t43mHxeb4wW8\ndFZ6+trnntO4TMxkA9ECQB+yCPgO1zisJWYuD46KISoesYhwHe5C1BQElQgi9bio\nU39fFo88w1pok23a2CZBEXguSvCvexeB68OggdDXvy0=\n-----END RSA PRIVATE KEY-----\n";
// String to encrypt
char *str = "1234";
ERR_load_crypto_strings();
BIO *bpo = BIO_new_mem_buf(b64_pKey, -1);
RSA *pubKey = PEM_read_bio_RSA_PUBKEY(bpo, NULL, NULL, NULL); …Run Code Online (Sandbox Code Playgroud) 我正在阅读关于公钥公钥加密的维基百科(http://en.wikipedia.org/wiki/Public-key_cryptography),其中包含:
在Diffie-Hellman密钥交换方案中,每一方生成公钥/私钥对并分发公钥......在获得彼此公钥的真实副本后,Alice和Bob可以离线计算共享密钥.例如,共享密钥可以用作对称密码的密钥.
我想知道如何在Java中实现这一目标?即,给定一个任意的公钥和一个任意的私钥,如何从中产生一个共享秘密?
为了更清楚:
Alice有一个公钥/私钥对key_pair_alice,
Bob有一个公钥/私钥对key_pair_bob,
假设我的理解是正确的,应该有一个方法combine_keys(),以便:
combine_keys(key_pair_alice.private, key_pair_bob.public) ==
combine_keys(key_pair_alice.public, key_pair_bob.private)
Run Code Online (Sandbox Code Playgroud)
我的问题是如何在Java中实现combine_keys()方法.
谢谢.
我正在研究一个使用OpenSSL进行基本RSA加密和解密的简单程序.它对于小消息(<16字节)工作正常,但对于任何事情都失败了.我知道公钥加密的局限性在于您无法加密任何比密钥大小更长的内容.在我的情况下,我使用的是1024位密钥,因此我应该使用128字节(由于填充可能会略微减少),对吗?如果是这样,那不是我正在经历的.
这是我的程序的输出,有15个字节:
Generating RSA keypair...done.
Message to encrypt: 0123456789ABCDE
16 bytes encrypted
Decrypted message: 0123456789ABCDE
Run Code Online (Sandbox Code Playgroud)
并且有16个字节:
Generating RSA keypair...done.
Message to encrypt: 0123456789ABCDEF
16 bytes encrypted
140153837057696:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:467:
Decrypted message: (null)
Run Code Online (Sandbox Code Playgroud)
似乎无论如何,只加密了16个字节.
我的加密功能(通过修复更新):
unsigned char* rsa_seal(EVP_PKEY *pub_key, unsigned char *msg, size_t **enc_msg_len, unsigned char **sym_key, int *sym_key_len, unsigned char **iv) {
size_t msg_len = strlen((char*)msg);
unsigned char *encrypt = malloc(EVP_PKEY_size(pub_key));
EVP_CIPHER_CTX *ctx = malloc(sizeof(EVP_CIPHER_CTX));
EVP_CIPHER_CTX_init(ctx);
*sym_key = malloc(EVP_PKEY_size(pub_key));
*iv = malloc(EVP_MAX_IV_LENGTH);
**enc_msg_len = 0;
if(!EVP_SealInit(ctx, EVP_aes_128_cbc(), sym_key, sym_key_len, …Run Code Online (Sandbox Code Playgroud) 我正在尝试解决WiX RemotePayload哈希问题,但我不确定该CertificatePublicKey属性是如何找到的.
例如,从WiX 3.6源代码中获取.NET 4.0软件包定义:
<Fragment>
<util:RegistrySearchRef Id="NETFRAMEWORK40"/>
<WixVariable Id="WixMbaPrereqPackageId" Value="NetFx40Redist" />
<WixVariable Id="WixMbaPrereqLicenseUrl" Value="$(var.NetFx40EulaLink)" />
<PackageGroup Id="NetFx40Redist">
<ExePackage
InstallCommand="/q /norestart /ChainingPackage "[WixBundleName]""
RepairCommand="/q /norestart /repair /ChainingPackage "[WixBundleName]""
UninstallCommand="/uninstall /q /norestart /ChainingPackage "[WixBundleName]""
PerMachine="yes"
DetectCondition="NETFRAMEWORK40"
Id="NetFx40Redist"
Vital="yes"
Permanent="yes"
Protocol="netfx4"
DownloadUrl="$(var.NetFx40RedistLink)"
Compressed="no"
Name="redist\dotNetFx40_Full_x86_x64.exe">
<RemotePayload
Size="50449456"
Version="4.0.30319.1"
ProductName="Microsoft .NET Framework 4"
Description="Microsoft .NET Framework 4 Setup"
CertificatePublicKey="672605E36DD71EC6B8325B91C5FE6971390CB6B6"
CertificateThumbprint="9617094A1CFB59AE7C1F7DFDB6739E4E7C40508F"
Hash="58DA3D74DB353AAD03588CBB5CEA8234166D8B99"/>
</ExePackage>
</PackageGroup>
</Fragment>
Run Code Online (Sandbox Code Playgroud)
来自wix36-sources\src\ext\NetFxExtension\wixlib\NetFx4.wxs
我能找到的SHA1 Hash与fciv -sha1 dotNetFx40_Full_x86_x64.exe...
58da3d74db353aad03588cbb5cea8234166d8b99 dotnetfx40_full_x86_x64.exe
我可以CertificateThumbprint通过文件的属性对话框轻松找到匹配,或者使用signtool它来显示以下输出
C:\redist>signtool verify …Run Code Online (Sandbox Code Playgroud) rsa ×4
c ×3
encryption ×3
java ×3
openssl ×3
android ×2
cryptography ×2
node.js ×2
authenticode ×1
bit ×1
code-signing ×1
openpgp ×1
openpgp.js ×1
private-key ×1
security ×1
wix ×1