java Bouncy Castle加密的有效负载从SAP PI中被破坏

piah890a  于 2023-06-20  发布在  Java
关注(0)|答案(1)|浏览(233)

问题

我正在使用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
    • 当地环境**
  • 简体中文(简体)
  • 操作系统:Windows 7 SP1
  • JDK版本:1.3
    • SAP PI环境 *
  • PI版本:7.0
  • Java运行时:Java(TM)2运行时环境标准版(版本= 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密钥对

    • 公钥**
  • ----开始PGP公钥块----
    版本:BCPG v1.47
    mQGhBFUMSHMRBADrMi7kuXATsOdtvG2TBhe + U + SRp7fCEJKhd4Xs27HsNZ82c954 sHXiAXT1g6chdD + R8ZYWL8LQ2Jsu69YpzdRWgLkR4BK0mvKtrW84gVjRC9jgCgmw VETvFU3b5wzJYOSX0@OhCQK7F8bptrNAhhmnR + cTfYnzRLnXlwTKG71KBwCg8nbw dccq7kyASZxbWz11d +3yvHEEE AL8THYETkpsGu/AWN6P3ffl6qXpX7LLPnccrnSHT M4MKuRVnRZUlBRAK4koWwkYgzmYNKcbJLk85 0814Im/Tl2 + 1 + HpYPuX7Cp + Hqyo2Y3VVZMA +1LlU + uXsMRQ6ce8GW7iuo31EVGxuSichgIb6G4k 9zfR3J + IP3kiGeLcd akZuA/jgGXGkCsPJwRXefIn79OyMMjGbb0FwLJLUat5M2XDoYr2AsZ6xKsybdJBM XFbwOsn6yNqhcKgIHn1kA/WgwM6L4AQQrw2KN/kue/p + qmcws2SdBzlmIcLcWbwl lQlrbp3UHxGW2oagv5myocardia@BUElF1HOQaV7tYi2mYvRAW3P8oQtA50ZXN0QGdtYWls LmNvbYhGBBMRAgAGBQJVDEh0AAoJEP@twmjt49AnCrgAnj/feW9MahLwrFgNyW6H RpC0odESAJ0TZy6Zs3AvhbMl8jHC/URS8i2P27kEDQR@DEh0EBAA///////////J D9qiIWjCNMTGYouA3BzRKQJOCIpnzHQCC76mOxObIlFKCHmONATd75UZs806Qxsw Kwpt8l8UN0/hNW1tUcJF5IW1dmJefsb0TELppjftawv/XLb0Brft7jhr + 1qJn6Wu nyQRfEsf5kkoZlHs5Fs9wgB8uKFjvwWY2kg2HFXTmmkWP6j9JM9fg2VdI9yjrZYc YvNWIIVSu57VKQdwlpZtZww1Tkq8mATxdGwIyhghfDKQXkYuNs474553LBgOhgOb J4Oi7Aeij7XFXfBvTFLJ3ivL9pVYFxg5lUl86pVq5RXSJhiY + gUQFXKOWoqqxC2t MxcNB@6M6hVIavfHLpk7PuFBFjb7wqK6nFXXQYMfbOXD4Wm4eTHq/WujNsJM9ce jJTgSiVhnc7j0i@0u5r8S/6BtmKCGTYdgJzPshqZFIfKxgXeyAMu + EXV3phXWx3 CYjAutlG4gjiT6B05asxQ9tb/OD9 EI5LgtEgqSEIARpyPBKnh + bXiHGaEL26WyaZ wycYavTiPBqUaDS2FQvaJYPpyirUTOjbu8LbBN6O + S6O/B10 QfvsqmKHxZR05rwF2Z spZPoJDDoiM7oYZRW + ftH2EpcM7i16 + 4G912IXBIHNAGkSfVsFqpk7TqmI2P3cGG/7fckKbAj030Nck0BjGZ//////////////8AAgIQ@b4lhJnxVfKtUBZTP65CtmiaMGM 7slmH2EEMd1WkgNMBawq2W9gEAkqgc8oSTC2BAjEdyV03pp/Q2TsbUHkVH4YnK/M K3N4 + hOrqMGfo8e1aptSFixmq6aXDozsQyMutAjg5sJOLdhW9dQN/@C9EVNnWF/Q/COB19QaX/ayyzQ8 + IJUwwLU4vajZopYq9Gg6H9WksAFQWQOfuhrvf6rAzjSeSR mjecXm +0Rkk 06waxP3ZvAgjqQGiQ + 3PS6DSZNDpbT2x1j8Fl92m7hr5Bo5d73CGrl Qeyh6VxEviSw2bLSLcQvvB + KYBCxY +6t445/r4ONR gFZPT8YlAnQv8fw + otkHjnE fQZxVdb0rtMQ5uGVilLKSjOirjPKBApg5d3m0rOtpQvLyF4Fz@xxM88aaeAP4RFg 7JWcGx1zdk3SQKM9p9bZ/pvNFiorJPTLgw9j1 + FnQasegnqJd8n6GetH + BnWDl BL YnFwo9RDIkw5v + uG9ZzWQfSgVg3QrWoxQQ9kCs0ro89zLLitdkfXM9aQRJ/dhYKj pJrLglg jGBDbG6Vv/JmxFdhe5bRRHBSFGkNfQQFTQ1//VyIPPZZtGOx317s4QmEo RDxLHgH1fzr41LsXvX2PpbLHXxTpIY7J + pe6yZlmzeXLLKF0ZqXnjkg2MX2x/+ Se IJn8ufW3q8LgBCcqiEYEGBECAAYFAlUMSHUACgkQ/23CaO3j0CeVYACfcP5ocfsB fCDlTfnmAv + CISHwpdcAn3TSeD6ftizjUcNBxQwnjqfKN3T8
    = CPWK
  • ----结束PGP公钥块----
    • 私钥(密码:“测试12345!")**
  • ----开始PGP私钥块----
    版本:BCPG v1.47

lQHoBFUMSMRBADrMi7kuXATsOdtvG2TBhe + U + SRp7fCEJKhd4Xs27HsNZ82c954 sHXiAXT1g6chdD + R8ZYWL8LQ2Jsu69YpzdRWgLkR4BK0mvKtrW84gVjRC9jgCgmw VETvFU3b5wzJYOSX0@OhCQK7F8bptrNAhhmnR + cTfYnzRLnXlwTKG71KBwCg8nbw dccq7kyASZxbWz11d +3yvHEEE AL8THYETkpsGu/AWN6P3ffl6qXpX7LLPnccrnSHT M4MKuRVnRZUlBRAK4koWwkYgzmYNKcbJLk85 0814Im/Tl2 + 1 + HpYPuX7Cp + Hqyo2Y3VVZMA +1LlU + uXsMRQ6ce8GW7iuo31EVGxuSichgIb6G4k 9zfR3J + IP3kiGeLcd akZuA/jgGXGkCsPJwRXefIn79OyMMjGbb0FwLJLUat5M2XDoYr2AsZ6xKsybdJBM XFbwOsn6yNqhcK gIHn1kA/WgwM6L4AQQrw2KN/kue/p + qmcws2SdBzlmIcLcWbwl lQlrbp3UHxGW2oagv5myocardia@BUElF1HOQaV7tYi2mYvRAW3P8oQ/gkDAjEsU2VRQwZQ YM1E4ZLx + XLpfEac9ewO5vxMJEEWnxymXYM1E4ZLx 3T6xlTkWAQC/nlWr5tpvckYiQgr5F3hn 1lAW/Wu3UPvjA4a0DnRlc3RAZ21haWwuY29tiEYEExECAA@FAlUMSHQACgkQ/23C aO3j0CcKuACeP995b0xqEvCsWA3JbodGkLSh0RIAnRPPLpmzcC + FsyXyMcL9 RFLy LY/bnQZABFUMSHQQEAD/////////////////8kP2qIhaMI0xMZii4DcHNEpAk4IimfMdAIL vqY7E5siUUoIeY40BN3vlRmzzTpDG zArCm3yXxQ3T + E1bW1RwkXkhbV2Yl5 + xvRM QummN +1rC/9ctvQGt +3uOGv7Womfpa6fJBF8Sx/@SShmUezkWz3CAHy4oWO/BZja SDYcVdOaaRY/qP0kz1 + DZV0j3KOtlhxi81YghVK7ntUpB3CWl@1nDDVOSryYBPF0 bAjKGCF8MpBeRi42zjvjnncsGA6GA5sng6LsB6KPtcVd8G9MUsneK8v2lVg XGDmV SXzqlWrlFdImGJj6BRAVco5aiqrELa0zFw0EUHozqFUhq98cumTs + 4UEWNvvCorq cVddBgx9s5cPhabh5Mer9a6M2wkz1x6MlOBKJWGdzuPSJhrS7mvxL/oG2YoIZNh2 AnM + yGpkUh8rGBd7IAy74RdXemFdbHcJiMC62UbiCOJPoHTlqzFD21v84P0QjkuC 0SCpIQgBGnI8 EqeH5teIcZoQvbpbJpnDJxhq90I8GpRoNLYVC9olg + nKKtRM6Nu7wtsE3o75Lo78FB ++ yqYofE FlHTmvAXZmylk + gkMOiIzuhlFb5 + 0fYSlwzuLXr7gb 3XYhcEgc0AaRJ9WwWqmTtOqYjY/dwYb/t 9yQpsCPTfQ1yTQGMZn/////////wAC AhAAtviWEmfFV8q1QFlM/rkK2aJowYzuyWYfYQQx3VaSA0wFrCrZb2AQCSqBzyhJ MLYECMR3JX Temn9DZOxtQeRUfhicr8wrc3j6E6uowZ + jx7Vqm1IWLGarppcOjOxD Iy60CODmwk4t2Fb11A3 + a AL0RU2dYX9D8I4HX1Bpf9rLLNDz4glTDAtTi9qNmili r0aDof1aSwAVBZA5 + 6Gu9/qsDONJ5JGa@5xeb7RGTTrBrE/dm8CCOpAaJD7c9LoN Jk0OltPbHWPwWX3abuGvkGjl3vcIauVB7KHpXES + JLD ZstItxC +8H4pgELFj7q3j jn + vg41GAVk9PxiUCdC/x/D6i2QeOcR9BnFV1vSu0xDm4ZWKUspKM6KuM8oECmDl 3ebSs62lC8vIXgXMLHEzzxpp4A/h F + DslZwbHXN2TdJAoz2n1tn + m80WKisk9MuD D2PX4WdBqx6Ceol3yfoZ60f4GdYOUEticXCj1@iTDm/64b1nNZB9KBWDdCtajFB D2QKzSujz3MsuK12R9cz1pBEn92FgqOkmsuCWCMYENsb3 pW/8mbEV2F7ltFEcFIUa Q19BAVNDX/9XIg89lm0Y7HfXuzhCYShEPEseAfV/OvjUuxe9fY + lssdfFOKH jsn6 l7rJmWbN5cssoXRmpeeOSDYxfbH/5J6Umfy59berwuAEJyr + CQMCMSxTZVFDBlBg sfC08oFwjbf2kp9qaHLORoOMbU/Fyjc343iR9 Ifo0HJtyrA37/BW4XCJzs + Z8CeT 0Cf6f22oErofdyS4w3TaO + yGgmUJ75BSbqveAU/4DJsl3 k +0vRSVgsphe3Nlh2P1 +8s9qtvIcRc27oSBDw2SG +rSTWEQrb9aJty6DekWHTjBXiCj6ZuZeJ@DxJ3Vs967 Ty4q + PFRNynp9na9aXa7H2LbkwY/HaKibi63BMJsDZJT/q1vWd3ZpbCv1xhtUnk02nQurC8 + L1/6xeoJv6/tCT00cHkWf + Fem3FSATZUA2yy4JT1yK7KFNgNSRF5b + k MLNiz4VMW + 5ym31YqVguD9JmD02qkgX4U5ATLnwvGXFaW4JRsODbX7I/08tRgcUe x + fURZwJF86rt@JxrCKJHWTd0GYb1/iZlRs0D6AZdlwKN3 + 6Dge/04d9g9BQ9giq HOmXFk5jE22wTOzq9VUES6HzBHCpq32GxYdQ7/4ZTLbQpw3whPsHcAeNmidxsGyG QmP/Xs757dnDsAmL9TQ1Ph1Uftc xuPHiPIsMBM44VMglBacfOnEDCTl8hHiNOKl + V + 8sg5PBd2OTJVKC95Oe4NIgYo1MCNZhDRNCyut1h1eMHkcQZfCxXvPTOBDR7HXz lcfHnxwkYQC3mSK5hMPT3IYSSihY6gRUrD62jj4w6X5HhAo5sRjcisT0lXYjtKx3 PDgfqHQU0CnmKqovVIwUuYYNn9aYM4hGBBgRAgAGBQJVDEh1AAoJEP9twmjt49An IWAAn3D + aHH7AXwg5U355gL/giEh8KXXAJ900ng + n7Ys41HDQcUMJ46nyjd0/A ===
= kuac

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

加密输出

    • Eclipse**
  • ----开始PGP消息-----
    版本:BCPG v1.47
    hQQOA0fjQmjVGrtrEA/+ JTCsjY1frycHtMDeTPYfmsRX/nnVuTTvB2c9ZkK3GJq + TF2kMXhG4x j8XO5c7DtIehKwIAMvvirpX456mnObGMUQMtguXvsCMuY766SmgRx6 GebHU0v166xkN/9ZmHBs@xti7P1qFAJe4XVAhNXb + odUGrnSPNfQY4gUvvP6DM7a azaCQygElNfhBP26XODKD8h2xJqyNxb@9HodEmVevrhvBPQFZvAcA0KLFX1hvWG9Us D4eOrZp0UL4KoabDtHcTvUILRqmgslX9oMMrEoPdEdkvWJTeZMf8Yf8S0aNoUtAB Rpi49n2kTiQcX5x313stxSaP9mcmyKsMAlXn0BgnWUS/w4GGGB6GW ki1OirHi2DG 3Q0LOMWlYrLinXq9C +3cHCSiBYhF6Z + D74L97YGNMtHPfZ6B/Q4B7B64RKJlmC/S 7k0aeyGSzYm35heBKifKs6gQiiiW352HppJsO vgsZr +0/p8BIMZtgJReFnZ/plsz0 vB3aoDYkUtNJR + WpwRYUnS4YR7Ga5/uqQvrFUBuyvOQdfsZJeL@zG6geyefBi183 GskEMOWHTdU5uUgI2LGzCpp1hOJ5 + O/KXdLUIF + r + Z/khp + qsJPVmxRRhAFuf0Uq 4outU5 wiq/cr0PJ9je3rcIpx6jku2FFzlf3CH6rVVrqU8jzHJOtrq5yKMsVLijeQQ AIUTlgkgXFzcl6P 1fuo73uZBY047twIq1pe7rW2rKZW7V5eZNM + FPgBjZ0NFu19A Ca9U5EobdNO2ZZxD4 + ye + GKtGdKmQ6I3 + B938tVnJYvRZwoc7oyKieO59oxuJGgG UkIx34ivVojvovpk5mojGL0Ne1@PV3mP +88r/EHmEuyVYiwj6zN5TP6WecEBBxAY EIJKae + GfArAW9fjIq + FRTNU6W3F5dhp3AasbUpI cS07exOzIy6zmhyUYchEFRWW/tKQzXT42zZySPicVI5NkepOvCwRIaTU/VYL12bMN26bvbZRXYoONxbOXjywOCy8 Xf9Shr/Uf9PUc9P3H0rCflHxCe + KeVya3FDNhIJzyOkE0LAR3BXididSV64UBrkN FBYZv4CAqzI5pyuGoK0Jfc5sCLVtPY06s9n/EocNQUmbRXCgOKv1dV9KSTByyR4J j3wQ8Vh/iIPYiP352VSsql2IrYHPhaNT12BrgD1wu9ZD3 + GKV33nbEiyPnsVbMLN 6PuMS7DnDyqQQIt5j5eg2 sM3t9UTs938DDIFdp1hCVY6YBvPRgMCB4Gni54yxfc8 QKn ++90yWR6Fu0pwnsD2WL6Pcqf3xD5r + ke + HG8FmYo8OwIkyLbHLCyacMvs6dhK ZZnlFNvRteSLDlhw0o + MF6RoC9hhJYwOlfWGOBqEM jYf0lkB3O1rt6maKwNG1ljt kG3lN0xRK5XMFPMMmzlZfI2xj4vMLlN +06uNnir9QSWqszOL 1aPhR511vr2bGj/Zx + zbU0p3wiR8D60s + 9PeuE24XBOfsyCg ==
    =/OMU
  • ---结束PGP消息----
    • SAP PI *
  • ----开始PGP消息-----
    版本:BCPG v1.47

hQQOA0fjQmjVGrtrEBAAh/d/hO + no + nonMzRJlLVnJeEcahzDTtCD9 + aIljOsLIu pUgyJlVZTGe6heqJw4R8 8V96Yc1BxsW0SkvcNyZ5HCraRyt1yeNQE4e6BgFI7J53 nBBb1d8Qd07YIRpiOgqaVDgluLa 7LXkFPjgmN2JEPXUSchtI73EEFYIxmeSwdyyY wKRi3kjcZu/MK9NJ74InWviFVQBumpyq9o4SdE@yrp8s/K3O2knzsV1es1as5yL Fdh4O0Rf8klWv8tb4hYdtGjtvpuETQoYP5vaXgWGqajkvfV ++@aYD2FPh4ENF9om 3jG + GoAwPNzaxe5RCJResIXuYj0wTig3S8xsJiLmrZC7/bMb8/JmhstoCv7192@3 jUg/Ao1Y5iwbp8GYx7h + DQuW81MuXJpaCXPfWSWnHinkqS0SC25v13i7YBSrKUYp tN75WAiX1zLZKAqseS/OIz9luRxtttxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxtxt@L8Ke4u9EWD7ywwSXuOoeNdSnl4Rl5RQ +9P qrNPjlMdoIZTw4h69TIJvbe9og0izgeI +1Jmu0B 7B8d/afkn2qKN8e/Vz7wcSPs6 tzS7U3yRuAW4wgExZATnNJXINIjuBX/tsvenWqhgofNOSY9wynZgYUUx@2vzia3 o9wWE8J5GI7uTsQzrWrDcuzwV9fZWVbeWKj6lO6p7pn8yvJlZPhsQPyhHAqBOBsP/2DLYjhIOcGi4CnqfVCvf8FZqqjPquol081rRCXaA2A9Q6rlMH1OcqTOBLjt78RL uw8t 2YtNxJX3uxsb9jVSznBBltN283ZLPO9IJERXffT + BL86S8hmhLXSkhQPmnRt ijYx6cAJNizLtzJzgrGbjL7o4s3Q8 + QFF2rqL3GcdySzdxM61l wVGYJ1MFyJqBCN ibLbz3u +8wovZ5F/0kOt54X4bG7YF31UrlcFam8b4cpHa3vdKJXRfXRwGRwG D82PCWo HDn33MeIkYOdQtBNDkNMl2DF6GcAaD2Z6R4F1S/h + ywW6HggD1OhKPiCu/xn8Ojy WWR3k Liqia0Tdz7dlBFBHxcNQM +1NtiZ9HAU + D71Evyx3R/ezBUrDiHnnZSujk1E Pvh1l5DH0vN788 VwDOBjKZRVx7Y7xlWl/oO6wlpLZ/SK0XN + x3jjeReDjnD7FPU/RtBddqgbfMap80VQ +5QXXG4za JKrkSj3jW4zW + W4 + msbMfS5MGzkFLkIHh9i5WCI JYsD31JQOb + rTr/UlCJWBdIC9FSlIKlvMPpHmBB + v853O/SYaBm3 Gme3or/xB5y9 Y58vK3M9bI9848qkivG2Q2XO + B4URSOTr8GTh8qZKDOYQ12kaWhC3Gc7rx M + N04c 6itSVNMX9ohUgLMidLShx5HcWPcdnb396nQCtP0gyDS30ksB6AJzvhVaNTlcyGYy bysww@n5fLq + AAI5vBdDiUFjTOX051y/jDKG1B26txgQLo0gCHiQnYYhtHQXe2kev wGSuO2 + 0v41 e9每单位=
= 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)));
    }
}
sdnqo3pr

sdnqo3pr1#

在进一步研究这个主题时,我发现了这个SCN post。它启发了我做三个改变来使它工作:

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

帖子中提到将密钥放入导入的存档中;这意味着如果需要的话很难更换,而且在每个环境(DEV,QA,LIVE...)中也很难使用不同的。我上面提供的代码使用PI值Map来设置每个环境中公钥的可配置完整文件路径。

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());
        }
    }
}

在下面的类中需要解决的一个重要问题是在创建PGPPublicKeyRingCollection之前使用PGPUtil.getDecoderStream,如下所述: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;
    }
}

相关问题