我尝试在这里实现解决方案 https://stackoverflow.com/a/33216302/4727842 .我的代码看起来像这样
private fun readPublicKey(input: InputStream): PGPPublicKey {
val publicKey = PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(input), BcKeyFingerprintCalculator())
var key: PGPPublicKey? = null
publicKey.keyRings.forEach { ring: PGPPublicKeyRing ->
ring.publicKeys.forEach { k: PGPPublicKey ->
if (k.isEncryptionKey) {
key = k
}
}
}
if (key == null) {
throw IllegalArgumentException("Can't find encryption key input key ring.")
} else {
return key!!
}
}
private fun encrypt(file: File): String {
val input = IOUtils.toInputStream("pub.asc", "UTF-8")
val key = readPublicKey(input)
Security.addProvider(BouncyCastleProvider())
val out = ByteArrayOutputStream()
val compressor = PGPCompressedDataGenerator(PGPCompressedData.ZIP)
PGPUtil.writeFileToLiteralData(compressor.open(out), PGPLiteralData.BINARY, file)
compressor.close()
val builder = BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.TRIPLE_DES)
val generator = PGPEncryptedDataGenerator(builder.setSecureRandom(SecureRandom()))
generator.addMethod(BcPublicKeyKeyEncryptionMethodGenerator(key))
return String(out.toByteArray())
}
使用 gpg cli (v2.2.15),生成 key 后,我输出 asc 文件。
gpg -ab -o ./pub.asc
它的内容是这样的
-----BEGIN PGP SIGNATURE-----
iQEzBAABCAAdFiEEpjyVE0VY1bLTdOo7wzVyPJ8SXFIFAlzbRfQACgkQwzVyPJ8S
XFKtjwgAp1ad9jFxKtsbzR4XT4HqypTPxpwY8raoIeXNg2PMDAFXGqmcRmP4NEBO
BYqalHAxrzXKVPcmKHtYnm7Jb91VLcYycsF+9RM53mwhg2YJhv49xROx8IsJuhVG
8X52nhPc+qQtzE/79FPDgiZNKSnrHUDvPU3rrZH44WPsGQJ9iGy0eoJPomuU29Cb
wWYxOHq8fRmL5h5Pi9mU1dJRZvHej8ewt0DpredY//7Er7xjCKHrFyzddSn1sGtv
QvoOP+1pLNCV/LKAgCz2N2vSOToLqYTuQlrO/kNApnza0+lO0GW4RMf0OJntbSIa
MHDa+/uc9YnyABkptxD2a9DsbvHwvg==
=QeFf
-----END PGP SIGNATURE-----
然后用线
val input = IOUtils.toInputStream("pub.asc", "UTF-8")
我试图逃跑。它在提取 key 失败后输出消息 “找不到加密 key 输入 key 环。”
。调试后我看到 publicKey.keyRings
大小为 0
。
我不明白这种情况,因为链接的指南似乎提倡使用 .asc
文件进行加密,而我认为它是用于签名的。我对 PGP 了解不多,但我认为这些是不同的步骤,并且我的用例可能不需要签名。
所以,我尝试导出公钥
gpg --export -a "User"> public.key
包含
-----BEGIN PGP PUBLIC KEY BLOCK-----
mQENBFzaBaIBCACngN7Zu5ZKKJuwlp9/iYLleIbYqTm1mxIVEsCiiksLTwbKIo2M
d7YeFDjJRPoKS94bt0FaRUV7cKwXTvqdVg0OITkTLE446TrMhi6Yz9InxkO1yC2l
RfVIZJgOfFBFTwiqx5HpPMmgHnpyzYESiwkNXR7mVIbIX4/5r+NOjMH/ioBSAd80
FV8Yl7k72B6gpbD/CEV6iR+uWlL99Bv6aYtbubCUEieY0KZyk998TFlatrtHvhDQ
ftVHYS4EsrnvlwtVD8QLbnYA2WsX6xVqpz8KHZ5LzXLys4D64sHZ5BkD3aX8Jp5s
iCpOb6rU4wdlD7gDJb1a1ks613C8Qj5/KHN1ABEBAAG0J0dyYXlkZW4gSG9ybWVz
IDxncmF5ZGVuLmhvcm1lc0BzYXAuY29tPokBVAQTAQgAPhYhBKY8lRNFWNWy03Tq
O8M1cjyfElxSBQJc2gWiAhsDBQkDwmcABQsJCAcCBhUKCQgLAgQWAgMBAh4BAheA
AAoJEMM1cjyfElxS2H0H/0O37sJfcNC2UFeuwoGqPMV4+3dN6sejpWBvQCw8OuGv
lDQmPUpEbBHs3awI83XlpYBbAKaDcJlIHPugM6CKGNWOL8RhL+ziJoGX1/Cldc5M
NHToNwU78/LE9Eog6oiC/VELnLP2qMRGK9+6sSYy7kz4zVPRzGjjD3t2uSxpoclO
LnF7Iqm6W+j2OIHACgBeqjjv4hgH4bJjXuixuPSxRLNp0dQ6PU8fj+xRjJudJWS6
hx3PM8/NZvoDruqEWjoTJW96S7askitImtcSw90kMbTpw/knZhpNeCJMQPF8jLUo
ZSbuC+8EukzuJ1mNxS9S0M1IX4psKEUttBYya+SoX/C5AQ0EXNoFogEIALk9vHyO
sXeqHEXeRsCHDyfOtFJlUFQvtkf3dwyyg4hVQq2vYTVyO+couxpgmCCrCzSNdlwK
Salh7Wejf+U+Erx8RzGJ764uyIlw/1B2qlGFgdWPaRWHtufQiUz6RNtWEhsBuddI
lbWxMOvbA3wfkFAIl+NQ8Aqqd8N9ao7mrXcADF7hRMtM+TllFJjxpNJeCWxwfeDf
EMM6totFf9CyD+Q0Zq6zyVFhgLiMuLPX4LsRMBKHGrg0LyyRQgDEezI1WH25YeAT
El8YJriEV4PcXQGnrsfkKbvsnNkXFb3nRlANuKlnHgBrSLE9Tqm4XuwG+czdGJuU
p0eyoxv4vrCGCgMAEQEAAYkBPAQYAQgAJhYhBKY8lRNFWNWy03TqO8M1cjyfElxS
BQJc2gWiAhsMBQkDwmcAAAoJEMM1cjyfElxSRuwH/3RZ6Zs5K76GaakJh0H5uw3H
mqrQiVSh1PmcGO2qRZuDrGDOiJWnOCnl48t71DgqjyABPAYsYzIhZXltA6lYVCI5
68HmUyfOHyeoZa6t35YM3A6S3jsIHRSQgu98R/1VK5EksQnGTrYwsa3gUQy+7BbN
F88+jRhEKnBYOABQ+M29pkx8zvH9UdrHWMTu2h5tb70volDSQzsdN9KX4EHoAto3
jP3janjIzYohBXM+FFte9HIOndwJ0RsZ5UD8lx8EmKh4DCUw3JxHagHOvdXopAAM
j+bUVTlu72LmvcsiNAKg7UicIuprKyHxDkSeelgEQt7Iz+6w3WL9djvL3hG3cks=
=9i+0
-----END PGP PUBLIC KEY BLOCK-----
并运行
val input = IOUtils.toInputStream("public.key", "UTF-8")
这没有产生任何变化。 bouncycaSTLe 在我的公钥文件中找不到任何 key 。然后我看到,由于我使用的是 gpg2,因此处理 key 环的方式有所不同。我在此处找到了将 .pkr
转换为 .kbx
的解决方案 https://stackoverflow.com/a/34221494/4727842但在这一点上,这已经变得非常复杂了。我不知道公钥环和公钥之间的区别。我不知道为什么第一个示例使用 .asc
文件作为假定有效的 key 环。我特别不知道为什么从我的 public.key
文件创建一个 bouncycaSTLe PGPPublicKey
对象如此困难。
最佳答案
如果您只想进行正确的加密/解密,请使用 bouncy-gpg (不要脸的外挂:我是作者)。
也不要使用 3DES,它太慢了而且不是最现代的算法(尽管它仍然被认为是安全的,AFAIK)。
您通过 gpg --export -a me@example.com
导出公钥。
您使用 InMemoryKeyring
管理 key (有关详细信息,请参阅 here):
public static KeyringConfig keyringConfigInMemoryForKeys(final String exportedPubKey, final String exportedPrivateKey, final String passphrase) throws IOException, PGPException {
final InMemoryKeyring keyring = KeyringConfigs.forGpgExportedKeys(KeyringConfigCallbacks.withPassword(passphrase);
keyring.addPublicKey(exportedPubKey.getBytes("US-ASCII"));
// you can add many more public keys
// if you only want to encrypt you do not need a private key and can ignore this line
keyring.addSecretKey(exportedPrivateKey.getBytes("US-ASCII"));
// you can add many more private keys
return keyring;
}
final String original_message = "I love deadlines. I like the whooshing sound they make as they fly by. Douglas Adams";
// Most likely you will use one of the KeyringConfigs.... methods.
KeyringConfig keyringConfigOfSender = keyringConfigInMemoryForKeys(..); // TODO - here comes your code to get keys
ByteArrayOutputStream result = new ByteArrayOutputStream();
try (
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(result);
final OutputStream outputStream = BouncyGPG
.encryptToStream()
.withConfig(keyringConfigOfSender)
.withStrongAlgorithms()
.toRecipients("recipient@example.com", "sender@example.com") // TODO - also your job to set the recipients
.andSignWith("sender@example.com") // TODO - same here
.binaryOutput()
.andWriteTo(bufferedOutputStream);
// Maybe read a file or a webservice?
final ByteArrayInputStream is = new ByteArrayInputStream(original_message.getBytes())
) {
Streams.pipeAll(is, outputStream);
// It is very important that outputStream is closed before the result stream is read.
// The reason is that GPG writes the signature at the end of the stream.
// This is triggered by closing the stream.
// In this example outputStream is closed via the try-with-resources mechanism of Java
}
result.close();
byte[] chipertext = result.toByteArray();
关于java - 充气城堡打开 gpg2 公钥,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56157995/