问题

我正在使用Bouncy Castle Java使用PGP加密文件。该程序可以在SAP PI 7.0中运行。当我对解密程序运行PI的输出(加密文件)时,我得到的空解密文件没有错误。

因此,我尝试使用相同的参数在Eclipse中加密相同的源文件。这次,我能够正确解密输出,以便检索我的原始文件。相同的代码,相同的输入。

在某个时候,我注意到PI输出比Eclipse的输出短几个字节(通常为32个字节)。我认为这就是解密输出为空而没有错误的原因。我不知道加密文件中可能缺少什么,因为两个PGP消息都具有相同的形状。

关于如何解决此问题的任何建议? PGP消息中是否缺少一部分?我是否错过了PI环境中的库或配置点?

技术细节

有弹性的城堡

  • 版本1.47
  • JDK:1.3
  • jar可从http://polydistortion.net/bc/download/下载:jce-jdk13-147.jar,bcpg-jdk13-147.jar

  • 当地环境
  • Java:1.6.0_45
  • 操作系统:Windows 7 SP1
  • JDK版本:1.3

  • SAP PI环境
  • PI版本:7.0
  • Java运行时:Java™2 ​​Runtime Environment,标准版(版本= 1.4.2_14-b05)
  • Java虚拟机:Java HotSpot(TM)64位服务器VM(版本= 1.4.2_14-b05)
  • 操作系统:Windows 2003(版本= 5.2,arch = amd64)
  • JDK版本:1.3

  • DSA密钥对

    公钥

    ----- BEGIN PGP公钥块-----

    版本:BCPG v1.47

    mQGhBFUMSHMRBADrMi7kuXATsOdtvG2TBhe + U + SRp7fCEJKhd4Xs27HsNZ82c954
    sHXiAXT1g6chdD + R8ZYWL8LQ2Jsu69YpzdRWgLkR4BK0mvKtrW84gVjRC9jgCgmw
    VETvFU3b5wzJYOSX0xOhCQK7F8bptrNAhhmnR + cTfYnzRLnXlwTKG7lKBwCg8nbw
    dccq7kyASZxbWz11d + 3yvHEEAL8THYETkpsGu / AWN6P3ffl6qXpX7LLPnccrnSHT
    M4MKuRVnRZUlBRAK4koWwkYgzmYNKcbJLk850814Im / Tl2 + 1 + HpYPuX7Cp + Hqyo2
    Y3VVZMA + 1LlU + uXsMRQ6ce8GW7iuo31EVGxuSichgIb6G4k9zfR3J + IP3kiGeLcd
    akZuA / jgGXGkCsPJwRXefIn79OyMMjGbb0FwLJLUat5M2XDoYr2AsZ6xKsybdJBM
    XFbwOsn6yNqhcKgIHn1kA / WgwM6L4AQQrw2KN / kue / p + qmcws2SdBzlmIcLcWbw1
    lQlrbp3UHxGW2oagv5myXBUElF1HOQaV7tYi2mYvRAW3P8oQtA50ZXN0QGdtYWls
    LmNvbYhGBBMRAgAGBQJVDEh0AAoJEP9twmjt49AnCrgAnj / feW9MahLwrFgNyW6H
    RpC0odESAJ0Tzy6Zs3AvhbMl8jHC / URS8i2P27kEDQRVDEh0EBAA /////////// J
    D9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxObIlFKCHmONATd75UZs806Qxsw
    Kwpt8l8UN0 / hNW1tUcJF5IW1dmJefsb0TELppjftawv / XLb0Brft7jhr + 1qJn6Wu
    nyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXTmmkWP6j9JM9fg2VdI9yjrZYc
    YvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhghfDKQXkYuNs474553LBgOhgOb
    J4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq5RXSJhiY + gUQFXKOWoqqxC2t
    MxcNBFB6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYMfbOXD4Wm4eTHq / WujNsJM9ce
    jJTgSiVhnc7j0iYa0u5r8S / 6BtmKCGTYdgJzPshqZFIfKxgXeyAMu + EXV3phXWx3
    CYjAutlG4gjiT6B05asxQ9tb / OD9EI5LgtEgqSEIARpyPBKnh + bXiHGaEL26WyaZ
    wycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O + S6O / BQfvsqmKHxZR05rwF2Z
    spZPoJDDoiM7oYZRW + ftH2EpcM7i16 + 4G912IXBIHNAGkSfVsFqpk7TqmI2P3cGG
    / 7fckKbAj030Nck0BjGZ ////////// 8AAgIQALb4lhJnxVfKtUBZTP65CtmiaMGM
    7slmH2EEMd1WkgNMBawq2W9gEAkqgc8oSTC2BAjEdyV03pp / Q2TsbUHkVH4YnK / M
    K3N4 + hOrqMGfo8e1aptSFixmq6aXDozsQyMutAjg5sJOLdhW9dQN / mgC9EVNnWF /
    Q / COB19QaX / ayyzQ8 + IJUwwLU4vajZopYq9Gg6H9WksAFQWQOfuhrvf6rAzjSeSR
    mjecXm + 0Rk06waxP3ZvAgjqQGiQ + 3PS6DSZNDpbT2x1j8Fl92m7hr5Bo5d73CGrl
    Qeyh6VxEviSw2bLSLcQvvB + KYBCxY + 6t445 / r4ONRgFZPT8YlAnQv8fw + otkHjnE
    fQZxVdb0rtMQ5uGVilLKSjOirjPKBApg5d3m0rOtpQvLyF4FzCxxM88aaeAP4Rfg
    7JWcGx1zdk3SQKM9p9bZ / pvNFiorJPTLgw9j1 + FnQasegnqJd8n6GetH + BnWDlBL
    YnFwo9RDIkw5v + uG9ZzWQfSgVg3QrWoxQQ9kCs0ro89zLLitdkfXM9aQRJ / dhYKj
    pJrLglgjGBDbG6Vv / JmxFdhe5bRRHBSFGkNfQQFTQ1 // VyIPPZZtGOx317s4QmEo
    RDxLHgH1fzr41LsXvX2PpbLHXxTpIY7J + pe6yZlmzeXLLKF0ZqXnjkg2MX2x / + Se
    lJn8ufW3q8LgBCcqiEYEGBECAAYFAlUMSHUACgkQ / 23CaO3j0CeVYACfcP5ocfsB
    fCDlTfnmAv + CISHwpdcAn3TSeD6ftizjUcNBxQwnjqfKN3T8

    = CPWK

    -----结束PGP公钥块-----

    私钥(密码:“TestPass12345!”)

    ----- BEGIN PGP私钥块-----

    版本:BCPG v1.47

    lQHoBFUMSHMRBADrMi7kuXATsOdtvG2TBhe + U + SRp7fCEJKhd4Xs27HsNZ82c954
    sHXiAXT1g6chdD + R8ZYWL8LQ2Jsu69YpzdRWgLkR4BK0mvKtrW84gVjRC9jgCgmw
    VETvFU3b5wzJYOSX0xOhCQK7F8bptrNAhhmnR + cTfYnzRLnXlwTKG7lKBwCg8nbw
    dccq7kyASZxbWz11d + 3yvHEEAL8THYETkpsGu / AWN6P3ffl6qXpX7LLPnccrnSHT
    M4MKuRVnRZUlBRAK4koWwkYgzmYNKcbJLk850814Im / Tl2 + 1 + HpYPuX7Cp + Hqyo2
    Y3VVZMA + 1LlU + uXsMRQ6ce8GW7iuo31EVGxuSichgIb6G4k9zfR3J + IP3kiGeLcd
    akZuA / jgGXGkCsPJwRXefIn79OyMMjGbb0FwLJLUat5M2XDoYr2AsZ6xKsybdJBM
    XFbwOsn6yNqhcKgIHn1kA / WgwM6L4AQQrw2KN / kue / p + qmcws2SdBzlmIcLcWbw1
    lQlrbp3UHxGW2oagv5myXBUElF1HOQaV7tYi2mYvRAW3P8oQ / gkDAjEsU2VRQwZQ
    YM1E4ZLx + XLpfEac9ewO5vxMJEEWnxym3T6xlTkWAQC / nlWr5tpvckYiQgr5F3hn
    1lAW / Wu3UPvjA4a0DnRlc3RAZ21haWwuY29tiEYEExECAAYFAlUMSHQACgkQ / 23C
    aO3j0CcKuACeP995b0xqEvCsWA3JbodGkLSh0RIAnRPPLpmzcC + FsyXyMcL9RFLy
    LY / bnQZABFUMSHQQEAD ///////// 8kP2qIhaMI0xMZii4DcHNEpAk4IimfMdAIL
    vqY7E5siUUoIeY40BN3vlRmzzTpDGzArCm3yXxQ3T + E1bW1RwkXkhbV2Yl5 + xvRM
    QummN + 1rC / 9ctvQGt + 3uOGv7Womfpa6fJBF8Sx / mSShmUezkWz3CAHy4oWO / BZja
    SDYcVdOaaRY / qP0kz1 + DZV0j3KOtlhxi81YghVK7ntUpB3CWlm1nDDVOSryYBPF0
    bAjKGCF8MpBeRi42zjvjnncsGA6GA5sng6LsB6KPtcVd8G9MUsneK8v2lVgXGDmV
    SXzqlWrlFdImGJj6BRAVco5aiqrELa0zFw0EUHozqFUhq98cumTs + 4UEWNvvCorq
    cVddBgx9s5cPhabh5Mer9a6M2wkz1x6MlOBKJWGdzuPSJhrS7mvxL / oG2YoIZNh2
    AnM + yGpkUh8rGBd7IAy74RdXemFdbHcJiMC62UbiCOJPoHTlqzFD21v84P0QjkuC
    0SCpIQgBGnI8EqeH5teIcZoQvbpbJpnDJxhq9OI8GpRoNLYVC9olg + nKKtRM6Nu7
    wtsE3o75Lo78FB ++ yqYofFlHTmvAXZmylk + gkMOiIzuhhlFb5 + 0fYSlwzuLXr7gb
    3XYhcEgc0AaRJ9WwWqmTtOqYjY / dwYb / t9yQpsCPTfQ1yTQGMZn ////////// wAC
    AhAAtviWEmfFV8q1QFlM / rkK2aJowYzuyWYfYQQx3VaSA0wFrCrZb2AQCSqBzyhJ
    MLYECMR3JXTemn9DZOxtQeRUfhicr8wrc3j6E6uowZ + jx7Vqm1IWLGarppcOjOxD
    Iy60CODmwk4t2Fb11A3 + aAL0RU2dYX9D8I4HX1Bpf9rLLNDz4glTDAtTi9qNmili
    r0aDof1aSwAVBZA5 + 6Gu9 / qsDONJ5JGaN5xeb7RGTTrBrE / dm8CCOpAaJD7c9LoN
    Jk0OltPbHWPwWX3abuGvkGjl3vcIauVB7KHpXES + JLDZstItxC + 8H4pgELFj7q3j
    jn + vg41GAVk9PxiUCdC / x / D6i2QeOcR9BnFV1vSu0xDm4ZWKUspKM6KuM8oECmDl
    3ebSs62lC8vIXgXMLHEzzxpp4A / hF + DslZwbHXN2TdJAoz2n1tn + m80WKisk9MuD
    D2PX4WdBqx6Ceol3yfoZ60f4GdYOUEticXCj1EMiTDm / 64b1nNZB9KBWDdCtajFB
    D2QKzSujz3MsuK12R9cz1pBEn92FgqOkmsuCWCMYENsbpW / 8mbEV2F7ltFEcFIUa
    Q19BAVNDX / 9XIg89lm0Y7HfXuzhCYShEPEseAfV / OvjUuxe9fY + lssdfFOkhjsn6
    l7rJmWbN5cssoXRmpeeOSDYxfbH / 5J6Umfy59berwuAEJyr + CQMCMSxTZVFDBlBg
    sfC08oFwjbf2kp9qaHLORoOMbU / Fyjc343iR9Ifo0HJtyrA37 / BW4XCJzs + Z8CeT
    0Cf6f22oErofdyS4w3TaO + yGgmUJ75BSbqveAU / 4DJsl3k + 0vRSVgsphe3Nlh2P1
    + 8s9qtvIcRc27oSBDw2SG + rSTWEQrb9aJty6DekWHTjBXiCj6ZuZeJxDxJ3Vs967 Ty4q + PFRNynp9na9aXa7H2LbkwY / HaKibi63BMJsDZJT / q1vWd3Zb
    02nQurC8 + L1 / 6xeoJv6 / tCT0OcHkWf + Fem3FSATZUA2yy4JT1yK7KFNgNSRF5b + k
    MLNiz4VmW + 5ym31YqVguD9JmD02qkgX4U5ATLnwvGXFaW4JRsODbX7I / 08tRgcUe
    x + fURZwJF86rtfJxrCKJHWTd0GYb1 / iZlRs0D6AZdlwKN3 + 6Dge / 04d9g9BQ9giq
    HOmXFk5jE22wTOzq9VUES6HzBHCpq32GxYdQ7 / 4ZTLbQpw3whPsHcAeNmidxsGyG
    QmP / Xs757dnDsAmL9TQ1Ph1UftcxuPHiPIsMBM44VMglBacfOnEDCTl8hHiNOK1 +
    V + 8sg5PBd2OTJVKC95Oe4NIgYo1MCNZhDRNCyut1h1eMHkcQZfCxXvPTOBDR7HXz
    lcfHnxwkYQC3mSK5hMPT3IYSSihY6gRUrD62jj4w6X5HhAo5sRjcisT0lXYjtKx3
    PDgfqHQU0CnmKqovVIwUuYYNn9aYM4hGBBgRAgAGBQJVDEh1AAoJEP9twmjt49An
    lWAAn3D + aHH7AXwg5U355gL / giEh8KXXAJ900ng + n7Ys41HDQcUMJ46nyjd0 / A ==

    =夸克

    -----结束PGP私钥块-----

    加密输出

    Eclipse

    -----开始PGP消息-----

    版本:BCPG v1.47

    hQQOA0fjQmjVGrtrEA / + JTCsjY1frycHtMDeTPYfmsRX / nnVuTTvB2c9ZkK3GJq +
    TF2kMXhG4xj8XO5c7DtIehKwIAMvvirpX456mnObGMUQMtguXvsCMuY766SmgRx6
    GebHU0v166xkN / 9ZmHBsQxti7P1qFAJe4XVAhNXb + odUGrnSPNfQY4gUvvP6DM7a
    azaCQygElNfhBP26XODKD8h2xJqyNF9HodEmVevrhvBPQFZvAcA0KLFX1hvWG9Us
    D4eOrZp0UL4KoabDtHcTvUILRqmgslX9oMMrEoPdEdkvWJTeZMf8Yf8S0aNoUtAB
    Rpi49n2kTiQcX5x313stxSaP9mcmyKsMAlXn0BgnWUS / w4GGGB6GWki1OirHi2DG
    3Q0LOMWlYrLinXq9C + 3cHCSiBYhF6Z + D74L97YGNMtHPfZ6B / Q4B7B64RKJlmC / S
    7k0aeyGSzYm35heBKifKs6gQiiW352HppJsOvgsZr + 0 / p8BIMZtgJReFnZ / plsz0
    vB3aoDYkUtNJR + WpwRYUnS4YR7Ga5 / uqQvrFUBuyvOQdfsZJeLxzG6geyefBi183
    GskEMOWHTdU5uUgI2LGzCpp1hOJ5 + O / KXdLUIF + r + Z / khp + qsJPVmxRRhAFuf0Uq
    4outUwiq / cr0PJ9je3rcIpx6jku2FFzlf3CH6rVVrqU8jzHJOtrq5yKMsVLIJeQQ
    AIUTlgkgXFzcl6P1fuo73uZBY047twIq1pe7rW2rKZW7V5eZNM + FPgBjZ0NFu19A
    Ca9U5EobdNO2ZZxD4 + ye + GKtGdKmQ6I3 + B938tVnJYvRZwoc7oyKieO59oxuJGgG
    UkIx34ivVojvovpk5mojGL0Ne1RPV3mP + 88r / EHmEuyVYiwj6zN5TP6WecEBBxAY
    EIJKae + GfArAW9fjIq + FRTNU6W3F5dhp3AasbUpIcS07exOzIy6zmhyUYchEFRWW
    / tKQzXT42zZySPicVI5NkepOvCwRIaTU / VYL12bMN26bvbZRXYoONxbOXjywOCy8
    Xf9Shr / Uf9PUc9P3H0rCflHxCe + KeVya3FDNhIJzyOkE0LAR3BXIdidSV64UBrkN
    FBYZv4CAqzI5pyuGoK0Jfc5sCLVtPY06s9n / EocNQUmbRXCgOKv1dV9KSTByyR4J
    j3wQ8Vh / iIPYiP352VSsql2IrYHPHaNT12BrgD1wu9ZD3 + GKV33nbEiyPnsVbMLN
    6PuMS7DnDyqQQIt5j5eg2sM3t9UTs938DDIFDp1hCVY6YBvPRgMCB4Gni54yxfc8
    QKn ++ 90yWR6Fu0pwnsD2WL6Pcqf3xD5r + ke + HG8FmYo8OwIkyLbHLCyacMvs6dhK
    ZZnlFNvRteSLD1hw0o + MF6RoC9hhJYwOlfWGOBqEMjYf0lkB3O1rt6maKwNG1ljt
    kG3lN0xRK5XMFPMmzlZfI2xj4vMLlN + 06uNnir9QSWqszOL1aPhR511vr2bGj / Zx
    + eSizjofZbU0p3wiR8D60s + 9PeuE24XbOfsyCg ==

    = / OMU

    -----结束PGP消息-----

    SAP PI

    -----开始PGP消息-----

    版本:BCPG v1.47

    hQQOA0fjQmjVGrtrEBAAh / d / hO + no + nonMzRJlLVnJeEcahzDTtCD9 + aIljOsLIu
    pUgyJ1VZTGe6heqJw4R88V96Yc1BxsW0SkvcNyZ5HCraRyt1yeNQE4e6BgFI7J53
    nBBb1d8Qd07YIRpiOgqaVDgluLa7LXkFPjgmN2JEPXUSchtI73EEFYIxmeSwdyyY
    wKRi3kjcZu / MK9NJ74InWviFVQBumpyq9o4SdEViyrp8s / K3O2knzsV1es1as5yL
    Fdh4O0Rf8klWv8tb4hYdtGjtvpuETQoYP5vaXgWGqajkvfV ++ IaYD2FPh4ENF9om
    3jG + GoAwPNzaxe5RCJResIXuYj0wTig3S8xsJiLmrZC7 / bMb8 / JmhstoCv7192h3
    jUg / Ao1Y5iwbp8GYx7h + DQuW81MuXJpaCXPfWSWnHinkqS0SC25v13i7YBSrKUYp
    tN75WAiX1zLZKAqseS / OIz9luRaxtpL8Ke4u9EWD7ywwSXuOoeNdSnl4Rl5RQ + 9P
    qrNPjlMdoIZTw4h69TIJvbe9og0izgeI + 1Jmu0B7B8d / afkn2qKN8e / Vz7wcSPs6
    tzS7U3yRuAW4wgExZATnNJXINIjuBX / tsvenWqhgofNOSY9wynZgYUUxBL2vzia3
    o9wWE8J5GI7uTsQzrWrDcuzwV9fZWVbeWKj6lO6p7pn8yvJlZPhsQPyhHAqBOBsP
    / 2DLYjhIOcGi4CnqfVCvf8FZqqjPquol081rRCXaA2A9Q6rlMH1OcqTOBLjt78RL
    uw8t2YtNxJX3uxsb9jVSznBBltN283ZLPO9IJERXffT + BL86S8hmhLXSkhQPmnRt
    ijYx6cAJNizLtzJzgrGbjL7o4s3Q8 + QFF2rqL3GcdySzdxM61lwVGYJ1MFyJqBCN
    ibLbz3u + 8wovZ5F / 0kOt54X4bG7YF31UrlcFam8b4cpHa3vdKJXRfXRwGD82PCWo
    HDn33MeIkYOdQtBNDkNMl2DF6GcAaD2Z6R4FlS / h + ywW6HggD1OhKPiCu / xn8Ojy
    WWR3kLiqia0Tdz7dlBFBHxcNQM + 1NtiZ9HAU + D71Evyx3R / ezBUrDiHnnZSujk1E
    Pvh1l5DH0vN788VwDOBjKZRVx7Y7xlWl / oO6wlpLZ / SK0XN + x3jjeReDjnD7FPU /
    RtBddqgbfMap80VQ + 5QXXG4zaJKrkSj3jW4zW + W4 + msbMfS5MGzkFLkIHh9i5WCI
    JYsD31JQOb + rTr / UlCJWBdIC9FSlIKlvMPpHmBB + v853O / SYaBm3Gme3or / xB5y9
    Y58vK3M9bI9848qkivG2Q2XO + B4URSOTr8GTh8qZKDOYQ12kaWhC3Gc7rxM + N04c
    6itSVNMX9ohUgLMidLShx5HcWPcdnb396nQCtP0gyDS30ksB6AJzvhVaNTlcyGYy
    byswfn5fLq + AAI5vBdDiUFjTOX051y / jDKG1B26txgQLo0gCHiQnYYhtHQXe2kev
    wGSuO2 + 0v41e9EachmU =

    = OL09

    -----结束PGP消息-----

    Java代码

    BcPGP.java
    public class BcPGP {
    
        private static final int BUFFER_SIZE = 1 << 16; // should always be power of
                                                        // 2
        private static final int KEY_FLAGS = 27;
        private static final int[] MASTER_KEY_CERTIFICATION_TYPES = new int[] { PGPSignature.POSITIVE_CERTIFICATION,
                PGPSignature.CASUAL_CERTIFICATION, PGPSignature.NO_CERTIFICATION, PGPSignature.DEFAULT_CERTIFICATION };
    
        public static PGPPublicKey readPublicKey(InputStream in) throws IOException, PGPException {
    
            PGPPublicKeyRingCollection keyRingCollection = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(in));
    
            //
            // we just loop through the collection till we find a key suitable for
            // encryption, in the real
            // world you would probably want to be a bit smarter about this.
            //
            PGPPublicKey publicKey = null;
    
            //
            // iterate through the key rings.
            //
            Iterator rIt = keyRingCollection.getKeyRings();
    
            while (publicKey == null && rIt.hasNext()) {
                PGPPublicKeyRing kRing = (PGPPublicKeyRing) rIt.next();
                Iterator kIt = kRing.getPublicKeys();
                while (publicKey == null && kIt.hasNext()) {
                    PGPPublicKey key = (PGPPublicKey) kIt.next();
                    if (key.isEncryptionKey()) {
                        publicKey = key;
                    }
                }
            }
    
            if (publicKey == null) {
                throw new IllegalArgumentException("Can't find public key in the key ring.");
            }
            if (!isForEncryption(publicKey)) {
                throw new IllegalArgumentException("KeyID " + publicKey.getKeyID() + " not flagged for encryption.");
            }
    
            return publicKey;
        }
    
        public static PGPSecretKey readSecretKey(InputStream in) throws IOException, PGPException {
    
            PGPSecretKeyRingCollection keyRingCollection = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(in));
    
            //
            // We just loop through the collection till we find a key suitable for
            // signing.
            // In the real world you would probably want to be a bit smarter about
            // this.
            //
            PGPSecretKey secretKey = null;
    
            Iterator rIt = keyRingCollection.getKeyRings();
            while (secretKey == null && rIt.hasNext()) {
                PGPSecretKeyRing keyRing = (PGPSecretKeyRing) rIt.next();
                Iterator kIt = keyRing.getSecretKeys();
                while (secretKey == null && kIt.hasNext()) {
                    PGPSecretKey key = (PGPSecretKey) kIt.next();
                    if (key.isSigningKey()) {
                        secretKey = key;
                    }
                }
            }
    
            // Validate secret key
            if (secretKey == null) {
                throw new IllegalArgumentException("Can't find private key in the key ring.");
            }
            if (!secretKey.isSigningKey()) {
                throw new IllegalArgumentException("Private key does not allow signing.");
            }
            if (secretKey.getPublicKey().isRevoked()) {
                throw new IllegalArgumentException("Private key has been revoked.");
            }
            if (!hasKeyFlags(secretKey.getPublicKey(), KeyFlags.SIGN_DATA)) {
                throw new IllegalArgumentException("Key cannot be used for signing.");
            }
    
            return secretKey;
        }
    
        /**
         * Load a secret key ring collection from keyIn and find the private key
         * corresponding to keyID if it exists.
         *
         * @param keyIn
         *            input stream representing a key ring collection.
         * @param keyID
         *            keyID we want.
         * @param pass
         *            passphrase to decrypt secret key with.
         * @return
         * @throws IOException
         * @throws PGPException
         * @throws NoSuchProviderException
         */
        public static PGPPrivateKey findPrivateKey(InputStream keyIn, long keyID, char[] pass) throws IOException, PGPException,
                NoSuchProviderException {
            PGPSecretKeyRingCollection pgpSec = new PGPSecretKeyRingCollection(PGPUtil.getDecoderStream(keyIn));
            return findPrivateKey(pgpSec.getSecretKey(keyID), pass);
    
        }
    
        /**
         * Load a secret key and find the private key in it
         *
         * @param pgpSecKey
         *            The secret key
         * @param pass
         *            passphrase to decrypt secret key with
         * @return
         * @throws PGPException
         */
        public static PGPPrivateKey findPrivateKey(PGPSecretKey pgpSecKey, char[] pass) throws PGPException {
            if (pgpSecKey == null)
                return null;
    
            PBESecretKeyDecryptor decryptor = new BcPBESecretKeyDecryptorBuilder(new BcPGPDigestCalculatorProvider()).build(pass);
            return pgpSecKey.extractPrivateKey(decryptor);
        }
    
        /**
         * decrypt the passed in message stream
         */
        public static void decryptFile(InputStream in, OutputStream out, InputStream keyIn, char[] passwd) throws Exception {
            Security.addProvider(new BouncyCastleProvider());
    
            in = org.bouncycastle.openpgp.PGPUtil.getDecoderStream(in);
    
            PGPObjectFactory pgpF = new PGPObjectFactory(in);
            PGPEncryptedDataList enc;
    
            Object o = pgpF.nextObject();
            //
            // the first object might be a PGP marker packet.
            //
            if (o instanceof PGPEncryptedDataList) {
                enc = (PGPEncryptedDataList) o;
            } else {
                enc = (PGPEncryptedDataList) pgpF.nextObject();
            }
    
            //
            // find the secret key
            //
            Iterator it = enc.getEncryptedDataObjects();
            PGPPrivateKey sKey = null;
            PGPPublicKeyEncryptedData pbe = null;
    
            while (sKey == null && it.hasNext()) {
                pbe = (PGPPublicKeyEncryptedData) it.next();
    
                sKey = findPrivateKey(keyIn, pbe.getKeyID(), passwd);
            }
    
            if (sKey == null) {
                throw new IllegalArgumentException("Secret key for message not found.");
            }
    
            InputStream clear = pbe.getDataStream(new BcPublicKeyDataDecryptorFactory(sKey));
    
            PGPObjectFactory plainFact = new PGPObjectFactory(clear);
    
            Object message = plainFact.nextObject();
    
            if (message instanceof PGPCompressedData) {
                PGPCompressedData cData = (PGPCompressedData) message;
                PGPObjectFactory pgpFact = new PGPObjectFactory(cData.getDataStream());
    
                message = pgpFact.nextObject();
            }
    
            if (message instanceof PGPLiteralData) {
                PGPLiteralData ld = (PGPLiteralData) message;
    
                InputStream unc = ld.getInputStream();
                int ch;
    
                while ((ch = unc.read()) >= 0) {
                    out.write(ch);
                }
            } else if (message instanceof PGPOnePassSignatureList) {
                throw new PGPException("Encrypted message contains a signed message - not literal data.");
            } else {
                throw new PGPException("Message is not a simple encrypted file - type unknown.");
            }
    
            if (pbe.isIntegrityProtected()) {
                if (!pbe.verify()) {
                    throw new PGPException("Message failed integrity check");
                }
            }
        }
    
        public static void encryptFile(OutputStream out, InputStream is, PGPPublicKey encKey, boolean armor,
                boolean withIntegrityCheck, int compressType, int encryptType) throws IOException, NoSuchProviderException,
                PGPException {
            System.out.println("Add BouncyCastleProvider");
            Security.addProvider(new BouncyCastleProvider());
    
            if (armor) {
                out = new ArmoredOutputStream(out);
            }
    
            ByteArrayOutputStream bOut = new ByteArrayOutputStream();
            PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(compressType);
    
            // setup temp file to hold source data - this is necessary when using
            // PGPUtil.writeFileToLiteralData which uses a file
            System.out.println("Creating a temp file...");
            File tempfile = File.createTempFile("pgp", null);
            FileOutputStream fos = new FileOutputStream(tempfile);
            int read = 0;
            byte[] inBytes = new byte[1024];
            while ((read = is.read(inBytes)) != -1) {
                fos.write(inBytes, 0, read);
            }
            fos.flush();
            fos.close();
            System.out.println("Temp file created at ");
            System.out.println(tempfile.getAbsolutePath());
    
            PGPUtil.writeFileToLiteralData(comData.open(bOut), PGPLiteralData.BINARY, new File(tempfile.getAbsolutePath()));
            comData.close();
    
            BcPGPDataEncryptorBuilder dataEncryptor = new BcPGPDataEncryptorBuilder(encryptType);
            dataEncryptor.setWithIntegrityPacket(withIntegrityCheck);
            dataEncryptor.setSecureRandom(new SecureRandom());
    
            PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(dataEncryptor);
            encryptedDataGenerator.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(encKey));
    
            byte[] outBytes = bOut.toByteArray();
            OutputStream cOut = encryptedDataGenerator.open(out, outBytes.length);
            cOut.write(outBytes);
            cOut.close();
            out.close();
            System.out.println("data encrypted");
        }
    
        public static void signEncryptFile(OutputStream out, String fileName, PGPPublicKey publicKey, PGPSecretKey secretKey,
                String password, boolean armor, boolean withIntegrityCheck) throws Exception {
    
            // Initialize Bouncy Castle security provider
            Provider provider = new BouncyCastleProvider();
            Security.addProvider(provider);
    
            if (armor) {
                out = new ArmoredOutputStream(out);
            }
    
            BcPGPDataEncryptorBuilder dataEncryptor = new BcPGPDataEncryptorBuilder(SymmetricKeyAlgorithmTags.TRIPLE_DES);
            dataEncryptor.setWithIntegrityPacket(withIntegrityCheck);
            dataEncryptor.setSecureRandom(new SecureRandom());
    
            PGPEncryptedDataGenerator encryptedDataGenerator = new PGPEncryptedDataGenerator(dataEncryptor);
            encryptedDataGenerator.addMethod(new BcPublicKeyKeyEncryptionMethodGenerator(publicKey));
    
            OutputStream encryptedOut = encryptedDataGenerator.open(out, new byte[BcPGP.BUFFER_SIZE]);
    
            // Initialize compressed data generator
            PGPCompressedDataGenerator compressedDataGenerator = new PGPCompressedDataGenerator(CompressionAlgorithmTags.ZIP);
            OutputStream compressedOut = compressedDataGenerator.open(encryptedOut, new byte[BcPGP.BUFFER_SIZE]);
    
            // Initialize signature generator
            PGPPrivateKey privateKey = findPrivateKey(secretKey, password.toCharArray());
    
            PGPContentSignerBuilder signerBuilder = new BcPGPContentSignerBuilder(secretKey.getPublicKey().getAlgorithm(),
                    HashAlgorithmTags.SHA1);
    
            PGPSignatureGenerator signatureGenerator = new PGPSignatureGenerator(signerBuilder);
            signatureGenerator.init(PGPSignature.BINARY_DOCUMENT, privateKey);
    
            boolean firstTime = true;
            Iterator it = secretKey.getPublicKey().getUserIDs();
            while (it.hasNext() && firstTime) {
                PGPSignatureSubpacketGenerator spGen = new PGPSignatureSubpacketGenerator();
                spGen.setSignerUserID(false, (String) it.next());
                signatureGenerator.setHashedSubpackets(spGen.generate());
                // Exit the loop after the first iteration
                firstTime = false;
            }
            signatureGenerator.generateOnePassVersion(false).encode(compressedOut);
    
            // Initialize literal data generator
            PGPLiteralDataGenerator literalDataGenerator = new PGPLiteralDataGenerator();
            OutputStream literalOut = literalDataGenerator.open(compressedOut, PGPLiteralData.BINARY, fileName, new Date(),
                    new byte[BcPGP.BUFFER_SIZE]);
    
            // Main loop - read the "in" stream, compress, encrypt and write to the
            // "out" stream
            FileInputStream in = new FileInputStream(fileName);
            byte[] buf = new byte[BcPGP.BUFFER_SIZE];
            int len;
            while ((len = in.read(buf)) > 0) {
                literalOut.write(buf, 0, len);
                signatureGenerator.update(buf, 0, len);
            }
    
            in.close();
            literalDataGenerator.close();
            // Generate the signature, compress, encrypt and write to the "out"
            // stream
            signatureGenerator.generate().encode(compressedOut);
            compressedDataGenerator.close();
            encryptedDataGenerator.close();
            if (armor) {
                out.close();
            }
        }
    
        // public static boolean verifyFile(InputStream in, InputStream keyIn,
        // String extractContentFile) throws Exception {
        // in = PGPUtil.getDecoderStream(in);
        //
        // PGPObjectFactory pgpFact = new PGPObjectFactory(in);
        // PGPCompressedData c1 = (PGPCompressedData) pgpFact.nextObject();
        //
        // pgpFact = new PGPObjectFactory(c1.getDataStream());
        //
        // PGPOnePassSignatureList p1 = (PGPOnePassSignatureList)
        // pgpFact.nextObject();
        //
        // PGPOnePassSignature ops = p1.get(0);
        //
        // PGPLiteralData p2 = (PGPLiteralData) pgpFact.nextObject();
        //
        // InputStream dIn = p2.getInputStream();
        //
        // IOUtils.copy(dIn, new FileOutputStream(extractContentFile));
        //
        // int ch;
        // PGPPublicKeyRingCollection pgpRing = new
        // PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(keyIn));
        //
        // PGPPublicKey key = pgpRing.getPublicKey(ops.getKeyID());
        //
        // FileOutputStream out = new FileOutputStream(p2.getFileName());
        //
        // ops.init(new BcPGPContentVerifierBuilderProvider(), key);
        //
        // while ((ch = dIn.read()) >= 0) {
        // ops.update((byte) ch);
        // out.write(ch);
        // }
        //
        // out.close();
        //
        // PGPSignatureList p3 = (PGPSignatureList) pgpFact.nextObject();
        // return ops.verify(p3.get(0));
        // }
    
        /**
         * From LockBox Lobs PGP Encryption tools.
         * http://www.lockboxlabs.org/content/downloads
         *
         * I didn't think it was worth having to import a 4meg lib for three methods
         *
         * @param key
         * @return
         */
        public static boolean isForEncryption(PGPPublicKey key) {
            if (key.getAlgorithm() == PublicKeyAlgorithmTags.RSA_SIGN || key.getAlgorithm() == PublicKeyAlgorithmTags.DSA
                    || key.getAlgorithm() == PublicKeyAlgorithmTags.EC || key.getAlgorithm() == PublicKeyAlgorithmTags.ECDSA) {
                return false;
            }
    
            return hasKeyFlags(key, KeyFlags.ENCRYPT_COMMS | KeyFlags.ENCRYPT_STORAGE);
        }
    
        /**
         * From LockBox Lobs PGP Encryption tools.
         * http://www.lockboxlabs.org/content/downloads
         *
         * I didn't think it was worth having to import a 4meg lib for three methods
         *
         * @param key
         * @return
         */
        private static boolean hasKeyFlags(PGPPublicKey encKey, int keyUsage) {
            if (encKey.isMasterKey()) {
                for (int i = 0; i != BcPGP.MASTER_KEY_CERTIFICATION_TYPES.length; i++) {
                    for (Iterator eIt = encKey.getSignaturesOfType(BcPGP.MASTER_KEY_CERTIFICATION_TYPES[i]); eIt.hasNext();) {
                        PGPSignature sig = (PGPSignature) eIt.next();
                        if (!isMatchingUsage(sig, keyUsage)) {
                            return false;
                        }
                    }
                }
            } else {
                for (Iterator eIt = encKey.getSignaturesOfType(PGPSignature.SUBKEY_BINDING); eIt.hasNext();) {
                    PGPSignature sig = (PGPSignature) eIt.next();
                    if (!isMatchingUsage(sig, keyUsage)) {
                        return false;
                    }
                }
            }
            return true;
        }
    
        /**
         * From LockBox Lobs PGP Encryption tools.
         * http://www.lockboxlabs.org/content/downloads
         *
         * I didn't think it was worth having to import a 4meg lib for three methods
         *
         * @param key
         * @return
         */
        private static boolean isMatchingUsage(PGPSignature sig, int keyUsage) {
            if (sig.hasSubpackets()) {
                PGPSignatureSubpacketVector sv = sig.getHashedSubPackets();
                if (sv.hasSubpacket(BcPGP.KEY_FLAGS)) {
                    if ((sv.getKeyFlags() & keyUsage) == 0) {
                        return false;
                    }
                }
            }
            return true;
        }
    }
    

    FileCopyPGP
    public class FileCopyPGP {
        static final String PUBLIC_KEY_PATH = "D:\\PGP\\public.asc";
        static final String PRIVATE_KEY_PATH = "D:\\PGP\\secret.asc";
        static final String PASSWORD = "TestPass12345!";
    
        static final String SOURCE_PATH = "D:\\PGP\\run\\Source.txt";
        static final String ENCRYPTED_PATH = "D:\\PGP\\run\\Encrypted.txt";
        static final String DECRYPTED_PATH = "D:\\PGP\\run\\Decrypted.txt";
    
        public static void encrypt(InputStream is, OutputStream os) {
            try {
                PGPPublicKey encKey = BcPGP.readPublicKey(new FileInputStream(new File(PUBLIC_KEY_PATH)));
                long start = System.currentTimeMillis();
                System.out.println("Encryption started");
                BcPGP.encryptFile(os, is, encKey, true, true, CompressionAlgorithmTags.UNCOMPRESSED,
                        SymmetricKeyAlgorithmTags.AES_256);
                System.out.println("Encryption ended successfully in " + (System.currentTimeMillis() - start) + "ms");
            } catch (IOException e) {
                System.out.println(e.getMessage());
            } catch (PGPException e) {
                System.out.println(e.getMessage());
            } catch (NoSuchProviderException e) {
                System.out.println(e.getMessage());
            }
        }
    
        public static void decrypt(InputStream is, OutputStream os) {
            try {
                long start = System.currentTimeMillis();
                System.out.println("Decryption started");
                BcPGP.decryptFile(is, os, new FileInputStream(new File(PRIVATE_KEY_PATH)), PASSWORD.toCharArray());
                System.out.println("Decryption ended successfully in " + (System.currentTimeMillis() - start) + "ms");
            } catch (FileNotFoundException e) {
                System.out.println(e.getMessage());
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
    
        public static void main(String[] args) throws FileNotFoundException {
            encrypt(new FileInputStream(new File(SOURCE_PATH)), new FileOutputStream(new File(ENCRYPTED_PATH)));
            decrypt(new FileInputStream(new File(ENCRYPTED_PATH)), new FileOutputStream(new File(DECRYPTED_PATH)));
        }
    }
    

    最佳答案

    在对该主题进行进一步研究时,我遇到了这个SCN post。它激发了我进行3处更改使其起作用:

  • 我使用邮政编码来激发我在
  • 上面给出的代码
  • 我将罐子替换为bcprov-ext-jdk14-145.jarbcpg-jdk14-145.jar
  • 我将jar文件直接安装到java / lib / ext文件夹中-在服务器级别(这需要一些PI配置)-而不是将它们作为IA导入到存储库中。

  • 该帖子提到将密钥放入导入的存档中;这意味着很难根据需要进行更换,而且还要在每种环境(DEV,QA,LIVE ...)中使用不同的环境。我上面提供的代码使用PI值映射来设置每个环境中公钥的可配置完整文件路径。
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.util.Map;
    
    import com.sap.aii.mapping.api.AbstractTrace;
    import com.sap.aii.mapping.api.StreamTransformation;
    import com.sap.aii.mapping.api.StreamTransformationConstants;
    import com.sap.aii.mapping.api.StreamTransformationException;
    import com.sap.aii.mapping.value.api.IFIdentifier;
    import com.sap.aii.mapping.value.api.IFRequest;
    import com.sap.aii.mapping.value.api.IFResponse;
    import com.sap.aii.mapping.value.api.XIVMFactory;
    import com.sap.aii.mapping.value.api.XIVMService;
    
    public class PGPEncryptor implements StreamTransformation {
        private Map param;
        private AbstractTrace trace;
        private String receiver = null;
        private static final String SOURCE_AGENCY = "YOUR_SOURCE_AGENCY";
        private static final String SOURCE_SCHEME = "YourKeyPath";
        private static final String TARGET_AGENCY = "YOUR_TARGET_AGENCY";
        private static final String TARGET_SCHEME = "YourKeyPath";
    
        public void setParameter(Map arg0) {
            param = arg0;
            trace = (AbstractTrace) param.get(StreamTransformationConstants.MAPPING_TRACE);
            receiver = (String) param.get(StreamTransformationConstants.RECEIVER_SERVICE);
        }
    
        public void execute(InputStream in, OutputStream out) throws StreamTransformationException {
            try {
                IFIdentifier sourceIdentifier = XIVMFactory.newIdentifier(SOURCE_AGENCY, SOURCE_SCHEME);
                IFIdentifier targetIdentifier = XIVMFactory.newIdentifier(TARGET_AGENCY, TARGET_SCHEME);
                IFRequest request = XIVMFactory.newRequest(sourceIdentifier, targetIdentifier, receiver);
                trace.addInfo("Value Mapping lookup value: " + receiver);
                IFResponse response = XIVMService.executeMapping(request);
                String encKey;
                if (response.hasTargetValues()) {
                    encKey = response.getSingleTargetValue();
                    trace.addInfo("Using key path: " + encKey);
                } else {
                    trace.addInfo("Value Mapping lookup parameters");
                    trace.addInfo("Source");
                    trace.addInfo("Context: " + sourceIdentifier.getContext() + ", Agency: " + SOURCE_AGENCY + ", Scheme: "
                            + SOURCE_SCHEME);
                    trace.addInfo("Target");
                    trace.addInfo("Context: " + targetIdentifier.getContext() + ", Agency: " + TARGET_AGENCY + ", Scheme: "
                            + TARGET_SCHEME);
                    trace.addInfo("Value: " + receiver);
                    throw new StreamTransformationException("Public key not found.");
                }
    
                // Encrypt the message
                long start = System.currentTimeMillis();
                trace.addInfo("Encryption started");
                new PGPCrypto().encrypt(encKey, in, out, trace);
                trace.addInfo("Encryption ended successfully in " + (System.currentTimeMillis() - start) + "ms");
            } catch (Exception e) {
                trace.addInfo(e.getMessage());
            }
        }
    }
    

    修复以下类中的一件事很重要,就是在创建PGPUtil.getDecoderStream之前使用PGPPublicKeyRingCollection,如下所述:http://www.coderanch.com/t/600592/Security/Bouncy-Castle-API-invalid-header
    import java.io.ByteArrayOutputStream;
    import java.io.DataOutputStream;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.UnsupportedEncodingException;
    import java.security.SecureRandom;
    import java.security.Security;
    import java.util.Date;
    import java.util.Iterator;
    
    import org.bouncycastle.jce.provider.BouncyCastleProvider;
    import org.bouncycastle.openpgp.PGPCompressedDataGenerator;
    import org.bouncycastle.openpgp.PGPEncryptedDataGenerator;
    import org.bouncycastle.openpgp.PGPLiteralData;
    import org.bouncycastle.openpgp.PGPLiteralDataGenerator;
    import org.bouncycastle.openpgp.PGPPublicKey;
    import org.bouncycastle.openpgp.PGPPublicKeyRing;
    import org.bouncycastle.openpgp.PGPPublicKeyRingCollection;
    import org.bouncycastle.openpgp.PGPUtil;
    
    import com.sap.aii.mapping.api.AbstractTrace;
    
    public class PGPCrypto {
    
        public void encrypt(String publicKeyPath, InputStream in, OutputStream out, AbstractTrace trace) throws Exception {
            try {
                encrypt(publicKeyPath, inputStreamToString(in), out, trace);
            } catch (Exception e) {
                trace.addInfo(e.getMessage());
                throw new Exception(e.toString());
            }
        }
    
        public void encrypt(String publicKeyPath, String inString, OutputStream out, AbstractTrace trace) throws Exception {
            try {
                Security.addProvider(new BouncyCastleProvider());
                InputStream keyStream = new FileInputStream(publicKeyPath);
                // Get Publik key
                PGPPublicKey key = readPublicKeyFromCol(keyStream);
                out = new DataOutputStream(out);
                ByteArrayOutputStream bOut = new ByteArrayOutputStream();
                PGPCompressedDataGenerator comData = new PGPCompressedDataGenerator(PGPCompressedDataGenerator.ZIP);
                writeStringToLiteralData(comData.open(bOut), inString);
                comData.close();
                // object that encrypts the data
                trace.addInfo("Trace1: Going to encrypt the data");
                PGPEncryptedDataGenerator cPk = new PGPEncryptedDataGenerator(PGPEncryptedDataGenerator.CAST5, new SecureRandom(),
                        "BC");
                cPk.addMethod(key);
                byte[] bytes = bOut.toByteArray();
                out = cPk.open(out, bytes.length);
                out.write(bytes);
                cPk.close();
                out.close();
            } catch (Exception e) {
                trace.addInfo(e.getMessage());
                throw new Exception(e.toString());
            }
        }
    
        private String inputStreamToString(InputStream in) {
            // read in stream into string.
            StringBuffer buf = new StringBuffer();
            try {
                InputStreamReader isr = null;
                // try UTF-8 conversion
                try {
                    isr = new InputStreamReader(in, "UTF-8");
                } catch (UnsupportedEncodingException e) {
                    // or atleast in natural encoding
                    isr = new InputStreamReader(in);
                }
                int c = 0;
                while ((c = isr.read()) != -1) {
                    buf.append((char) c);
                }
                in.close();
                isr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return buf.toString();
        }
    
        private void writeStringToLiteralData(OutputStream out, String inString) throws IOException {
            PGPLiteralDataGenerator lData = new PGPLiteralDataGenerator();
            OutputStream pOut = lData.open(out, PGPLiteralData.BINARY, "", inString.length(), new Date());
            pOut.write(inString.getBytes());
            lData.close();
        }
    
        private PGPPublicKey readPublicKeyFromCol(InputStream in) throws Exception {
            PGPPublicKeyRing pkRing = null;
            PGPPublicKey result = null, key = null;
            try {
                PGPPublicKeyRingCollection pkCol = new PGPPublicKeyRingCollection(PGPUtil.getDecoderStream(in));
                Iterator it = pkCol.getKeyRings();
                while (it.hasNext()) {
                    pkRing = (PGPPublicKeyRing) it.next();
                    Iterator pkIt = pkRing.getPublicKeys();
                    while (pkIt.hasNext()) {
                        key = (PGPPublicKey) pkIt.next();
                        if (key.isEncryptionKey()) {
                            result = key;
                            break;
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new Exception(e.toString());
            }
            return result;
        }
    }
    

    10-08 18:29