📄 smimeutilities.java
字号:
return result; } public MimeMessage buildSMimeMessage( Session session, Message msg, InternetAddress fromAddr, InternetAddress[] recipAddrs, boolean sign, boolean clearSign, boolean envelope ) throws MessagingException { if ( Package.DEBUG && Package.isTraceable( "SMimeUtilities" ) ) { System.out.println( "SMimeUtilities.buildSMimeMessage(s,m,i,i,s,c,e)" ); } DataHandler dh = null; MimeMessage smimeMsg = null; MimeMultipart clearMultiPart = null; try { SecurityConfig cfgSec = SecurityConfig.getInstance(); ByteArrayOutputStream rawOut = new ByteArrayOutputStream(); msg.writeTo( rawOut ); byte[] rawBytes = rawOut.toByteArray(); // // FIRST wrap the MIME message inside a PKCS7 // Signed contentInfo in an SMIME pkcs7 part // String fromStr = fromAddr.getAddress(); Data rawData = encodeData( rawBytes ); if ( sign ) { PrivateKey pKey = cfgSec.getPrivateKey( fromStr ); X509Certificate[] certs = cfgSec.getIDCertificateChain( fromStr ); if ( pKey == null ) throw new MissingCertificateException( fromStr + " (private key)" ); if ( certs == null ) throw new MissingCertificateException( fromStr ); SignedData signedData = clearSign ? encodeClearSignedData( rawData, certs, pKey ) : encodeSignedData( rawData, certs, pKey ); ContentInfo contentInfo = encodeContentInfo( signedData ); ContentInfoSource signDs = new ContentInfoSource( contentInfo, ( clearSign ? "smime.p7s" : "smime.p7m" ), ( clearSign ? "application/pkcs7-signature" : "application/pkcs7-mime" ) ); dh = new DataHandler( signDs ); if ( clearSign ) { String subType = "signed; " + "protocol=\"application/pkcs7-signature\"; " + "micalg=sha1"; clearMultiPart = new MimeMultipart( subType ); MimeBodyPart signPart = new MimeBodyPart(); signPart.setDataHandler( dh ); signPart.setDisposition( Part.ATTACHMENT ); signPart.setFileName( "smime.p7s" ); SMimeBodyPart clearPart = new SMimeBodyPart( new ByteArrayInputStream( rawBytes ) ); clearPart.updateHeaders(); clearMultiPart.addBodyPart( clearPart ); clearMultiPart.addBodyPart( signPart ); } else if ( envelope ) { SMimeBodyPart signPart = new SMimeBodyPart(); signPart.setDataHandler( dh ); signPart.updateHeaders(); ByteArrayOutputStream signOut = new ByteArrayOutputStream(); signPart.writeTo( signOut ); byte[] signedBytes = signOut.toByteArray(); rawData = encodeData( signedBytes ); } } // // SECOND wrap the Signed contentInfo inside a PKCS7 // Enveloped contentInfo in an SMIME pkcs7 part // if ( envelope ) { X509Certificate[] recipCerts = cfgSec.getRecipientCertificates( recipAddrs ); EnvelopedData envelopedData = encodeEnvelopedData( rawData, recipCerts, AlgorithmID.rc2_CBC, 40 ); ContentInfo contentInfo = encodeContentInfo( envelopedData ); ContentInfoSource envDs = new ContentInfoSource( contentInfo, "smime.p7m", "application/x-pkcs7-mime" ); dh = new DataHandler( envDs ); } // // THIRD wrap the Enveloped contentInfo inside a // standard RFC822 headered SMIME message. // smimeMsg = new MimeMessage( session ); if ( clearSign ) { smimeMsg.setContent( clearMultiPart ); } else { smimeMsg.setDataHandler( dh ); } smimeMsg.saveChanges(); } catch ( Exception ex ) { throw new MessagingException( ex.toString() ); } return smimeMsg; } /** * Encode a String as an ASN1 Data object. */ public Data encodeData( String string ) { return encodeData( string.getBytes() ); } /** * Encode a byte array as an ASN1 Data object. */ public Data encodeData( byte ab[] ) { return new Data( ab ); } /** * Encode a PKCS7Content as an ASN1 SignedData object. */ public SignedData encodeSignedData( PKCS7Content pKCS7Content, X509Certificate[] certs, PrivateKey privateKey ) throws NoSuchAlgorithmException, IOException, CodingException, PKCSParsingException, PKCSException { SignedData signedData = null; InputStream inData = null; if ( pKCS7Content.getContentType().equals( ObjectID.pkcs7_data ) ) { inData = ((Data)pKCS7Content).getInputStream(); } else { inData = new ByteArrayInputStream( DerCoder.encode( pKCS7Content.toASN1Object() ) ); } IssuerAndSerialNumber issuerAndSerialNumber = new IssuerAndSerialNumber( certs[ certs.length - 1 ] ); SignerInfo signerInfo = new SignerInfo( issuerAndSerialNumber, AlgorithmID.sha1, AlgorithmID.rsaEncryption, privateKey ); Attribute attrs[] = new Attribute[2]; ASN1Object[] aObjs0 = { ObjectID.pkcs7_data }; attrs[0] = new Attribute( ObjectID.contentType, aObjs0 ); ASN1Object[] aObjs1 = { (new ChoiceOfTime()).toASN1Object() }; attrs[1] = new Attribute( ObjectID.signingTime, aObjs1 ); signerInfo.setAuthenticatedAttributes( attrs ); signedData = new SignedData( inData, SignedData.IMPLICIT ); signedData.setCertificates( certs ); SignerInfo[] infos = new SignerInfo[1]; infos[0] = signerInfo; signedData.setSignerInfos( infos ); ByteArrayOutputStream byteArrayOutputStream2 = new ByteArrayOutputStream(); signedData.writeTo( byteArrayOutputStream2 ); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( byteArrayOutputStream2.toByteArray() ); ASN1 aSN1 = new ASN1( byteArrayInputStream ); ASN1Object aSN1Object = aSN1.toASN1Object(); byteArrayInputStream = new ByteArrayInputStream( DerCoder.encode( aSN1Object ) ); signedData = new SignedData( byteArrayInputStream ); signedData.asn1_object = aSN1Object; return signedData; } public SignedData encodeClearSignedData( PKCS7Content pKCS7Content, X509Certificate[] certs, PrivateKey privateKey ) throws NoSuchAlgorithmException, IOException, CodingException, PKCSParsingException, PKCSException { SignedData signedData = null; InputStream inData = null; if ( pKCS7Content.getContentType().equals( ObjectID.pkcs7_data ) ) { inData = ((Data)pKCS7Content).getInputStream(); } else { inData = new ByteArrayInputStream( DerCoder.encode( pKCS7Content.toASN1Object() ) ); } IssuerAndSerialNumber issuerAndSerialNumber = new IssuerAndSerialNumber( certs[ certs.length - 1 ] ); SignerInfo signerInfo = new SignerInfo( issuerAndSerialNumber, AlgorithmID.sha1, AlgorithmID.rsaEncryption, privateKey ); Attribute attrs[] = new Attribute[2]; ASN1Object[] aObjs0 = { ObjectID.pkcs7_data }; attrs[0] = new Attribute( ObjectID.contentType, aObjs0 ); ASN1Object[] aObjs1 = { (new ChoiceOfTime()).toASN1Object() }; attrs[1] = new Attribute( ObjectID.signingTime, aObjs1 ); signerInfo.setAuthenticatedAttributes( attrs ); signedData = new SignedData( inData, SignedData.EXPLICIT ); signedData.setCertificates( certs ); signedData.addSignerInfo( signerInfo ); InputStream inputStream = signedData.getInputStream(); if ( inputStream != null ) { byte ab2[] = new byte[ 8 * 1024 ]; for ( ; ; ) { int numRead = inputStream.read( ab2 ); if ( numRead == -1 ) break; } ab2 = null; } // The following "Clone" code appears to properly create // the "no content" SignedData for the CLEAR_SIGNED case. ByteArrayOutputStream byteArrayOutputStream2 = new ByteArrayOutputStream(); signedData.writeTo( byteArrayOutputStream2 ); ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream( byteArrayOutputStream2.toByteArray() ); ASN1 aSN1 = new ASN1( byteArrayInputStream ); ASN1Object aSN1Object = aSN1.toASN1Object(); byteArrayInputStream = new ByteArrayInputStream( DerCoder.encode( aSN1Object ) ); signedData = new SignedData( byteArrayInputStream ); signedData.asn1_object = aSN1Object; return signedData; } /** * Encode a PKCS7Content as an ASN1 EnvelopedData object. */ public EnvelopedData encodeEnvelopedData( PKCS7Content content, X509Certificate recipCerts[], AlgorithmID algorithmID, int keyLen ) throws IOException, PKCSException, NoSuchAlgorithmException { EnvelopedData envelopedData = null; ByteArrayInputStream byteArrayInputStream1 = null; ByteArrayOutputStream byteArrayOutputStream1 = new ByteArrayOutputStream(); if ( content.getContentType().equals( ObjectID.pkcs7_data ) ) { byteArrayInputStream1 = new ByteArrayInputStream( ((Data) content).getData() ); } else { DerCoder.encodeTo( content.toASN1Object(), byteArrayOutputStream1 ); byteArrayInputStream1 = new ByteArrayInputStream( byteArrayOutputStream1.toByteArray() ); } envelopedData = new EnvelopedData( byteArrayInputStream1, content.getContentType(), algorithmID, keyLen ); RecipientInfo recips[] = new RecipientInfo[ recipCerts.length ]; for ( int j = 0 ; j < recips.length ; j++) { recips[j] = new RecipientInfo( recipCerts[j], AlgorithmID.rsaEncryption ); } envelopedData.setRecipientInfos( recips ); ByteArrayOutputStream byteArrayOutputStream2 = new ByteArrayOutputStream(); envelopedData.writeTo( byteArrayOutputStream2 ); ByteArrayInputStream byteArrayInputStream2 = new ByteArrayInputStream( byteArrayOutputStream2.toByteArray() ); envelopedData = new EnvelopedData( byteArrayInputStream2 ); return envelopedData; } /** * Encode a PKCS7Content as an ASN1 ContentInfo object. */ public ContentInfo encodeContentInfo( PKCS7Content pKCS7Content ) { return new ContentInfo( pKCS7Content ); } public class SMimeBodyPart extends MimeBodyPart { public SMimeBodyPart() throws MessagingException { super(); } public SMimeBodyPart( InputStream is ) throws MessagingException { super( is ); } public SMimeBodyPart( InternetHeaders headers, byte[] content ) throws MessagingException { super( headers, content ); } public void updateHeaders() throws MessagingException { super.updateHeaders(); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -