# Abspeichern von OutputStream



## Leno (3. Aug 2011)

Hi ,

habe mal eine weitere Frage ich habe es endlich geschafft mit Java ein PKCS7 Format zu erzeugen meine Methode liefert mit einen OutputStream, jetzt meine Frage wie kann ich diesen OutputStream Lokal auf meiner Festplatte speichrn als z.B. unter C:/ ...  


```
OutputStream out = unterzeichnen(mKey,myCert,daten ); // hier die Erzeugung des PKCS7 

FileOutputStream f= new FileOutputStream("C:\\ssl\\certs\\test.pkcs7");
		ObjectOutputStream s = new ObjectOutputStream(out);
		s.writeObject(out;
		s.close();
```

leider funktioniert der Obige ansatz gar nicht bekomme folgende Fehlermeldung :
 java.io.NotSerializableException:

Jemand ne Ahnung ??? wie ich das hinbekommen kann ?

Danke für alle Hilfe ; )


----------



## SlaterB (3. Aug 2011)

du meine Güte, ein Stream ist etwas was man absolut nicht speichern kann,
schon gar nicht auf so verrückte Wege wie in deinem Code

poste mal deine unterzeichnen()-Methode, um was geht es denn, beschreibe in Worten bisher schon alles passiert

immer gut: versuche die Ergebnisse, die du speichern willst, mit System.out.println() auszugeben,
wenn das geht, dann ist alles weitere Standardaufgabe, 
wenn das nicht geht, dann liegen Probleme in ganz anderen Bereichen als im 'Abspeichern'


----------



## Leno (3. Aug 2011)

Also es geht darum ich will bzw. muss ein X509 und eine Message in ein PKCS7 Format einhüllen.
Das Zert habe ich mir bereits erstellt. Jetzt möchte ich dieses PKCS7 Format auf meiner Festplatte Lokal speichrn ich könnte natürlich das Return in der Methode ändern nämhlich in PKCS7. 



```
public static void main(String[] args) throws CertificateException, IOException, NoSuchAlgorithmException, SignatureException {
		// TODO Auto-generated method stub

		
		// Reinladen von CetrifikatsDatei
		FileInputStream in = new FileInputStream("C:\\ssl\\certs\\CoCo.cer");

		CertificateFactory cer = CertificateFactory.getInstance("X.509");
		// Erzeugung des Cert
		X509Certificate myCert = (java.security.cert.X509Certificate) cer
				.generateCertificate(in);
		
		
		// Übergabebpararmeter für die Methode 
		// Encoded liedert verschlüsselte Daten als arrayZurück.
		//byte [] daten = myCert.getEncoded(); 
		
		// Aufrufen der Methode generatePrivateKey erzeugt einen Privaten Schlüssel um die Datei zu signieren.
		PrivateKey mKey = generatePrivateKey();
		
		
		// Die Message 
		
		String nachricht = "Hallo";
		
		byte [] daten = nachricht.getBytes();
		
		
		
		
		// ruf die Methode unterzeichnen auf die 
		// rückgabetyp ist dabei das PKCS 7 Format 
		//PKCS7 p = unterzeichnen(mKey,myCert,daten );
		
		OutputStream out = unterzeichnen(mKey,myCert,daten );
		/*
		// Problem mit speierhn auf Platte nich so leicht.
		System.out.println(out);
		
		FileOutputStream f= new FileOutputStream("C:\\ssl\\certs\\test.pkcs7");
		ObjectOutputStream s = new ObjectOutputStream(out);
		s.writeObject();
		s.close();
		
		/*
		 
		
		
		
	
		// Frage wie als PKCS ausgeben? 
		
		/*
		String source = p.toString();
			byte buf[] = source.getBytes(); 
			
			// Solch ein Cert als p7b Zertifikat angeben. p7s Sigantur  eventuell auch   p7m MIME  Nachricht
			OutputStream fo = new FileOutputStream("C:\\ssl\\certs\\CoCo.pkcs7"); 
		
			
			//i += 2
    		
			for (int i=0; i < buf.length; i++) {
				
				fo.write(buf[i]);
    		
    		}	
		
    	
    		
    		
    	SignerInfo [] info = p.getSignerInfos();
    	
    	for ( int i = 0 ; i < info.length ; i++ ){
    		
    		System.out.println(info[i]);
    		
    	}
    	
    	
    	*/
    	
		
		
		
		
		
		
		
		
		
		
	}
```


Sorry wegen dem Total unübersichtlichen CODE 










```
public static  OutputStream unterzeichnen( PrivateKey mKey, X509Certificate myCert,
			byte[] daten) throws FileNotFoundException {

		//FileOutputStream out = new FileOutputStream("C:\\ssl\\certs\\");
		// Ausgabe

		// Sind Variablen die wichtigen Daten beeinhalten.
		OutputStream ausgabe = new ByteArrayOutputStream();
		
		String digestAlgorithm = "SHA1"; // FesteWerte die wir später benötigern
		String signingAlgorithm = "SHA1withRSA"; // der Algom mit dem das ganze
													// Signiert wurde
		PrivateKey priv = mKey; // PrivateKey uns zu anfang noch null.
		X509Certificate x509 = myCert;

		PKCS7 p7 = null;
		
		try {

			AlgorithmId[] digestAlgorithmIds = new AlgorithmId[] { AlgorithmId
					.get(digestAlgorithm) };

			MessageDigest md = MessageDigest.getInstance(digestAlgorithm); // DigestAlgo
																			// SHA1
																			// wird
																			// übergeben.

			md.update(daten); // Daten welche Daten sogennante EinwegHast ist
								// das MessageDigest.
								// die Daten werden sozusgaen zuerst
								// initialisiert. mit Update.

			byte[] digestedContent = md.digest(); // liefert den HashWert an den
													// digestedContent weiter.

			// Wieso dieser teil kommt weiß ich nicht so genau anscheinend
			// liefert es wichtige Infors
			// wie z.B. wann das das Attribute signiert wurd mit welchem Algo
			// usw...
			
			PKCS9Attribute[] authenticatedAttributeList = {
					new PKCS9Attribute(PKCS9Attribute.CONTENT_TYPE_OID,
							ContentInfo.DATA_OID),
					new PKCS9Attribute(PKCS9Attribute.SIGNING_TIME_OID,
							new java.util.Date()),
					new PKCS9Attribute(PKCS9Attribute.MESSAGE_DIGEST_OID,
							digestedContent) };

			// Eine neue Attributsliste wird mit den Attributen erstellt.
			PKCS9Attributes authenticatedAttributes = new PKCS9Attributes(
					authenticatedAttributeList);

			// hier wird das Cert erstellt wobei der keyStore dafür genutzt wird
			// anscheinden.
			
			
			
			//--> nicht notwendig //x509 = (X509Certificate) keyStore.getCertificateChain(alias)[0];
			
			
			// das alias ist der Alias name des Zertifikates unterdem der dieses
			// Cert bekannt ist.
			// daraus wird dann der PrivateKey genommen.
		// Nicht notwendig--> //priv = (PrivateKey) keyStore.getKey(alias, null);

			
			
			// hier wird eine Siganture erzeugt mit dem SignierungsAlgo
			Signature signer = Signature.getInstance(signingAlgorithm);
			// der Private schlüsselwird signiert.
			signer.initSign(priv);
			
			// ???
			signer.update(authenticatedAttributes.getDerEncoding());
			
			
			
			byte[] signedAttributes = signer.sign();
			
			// die ConentInfo wird angelegt fpr das Cert.
			ContentInfo contentInfo = null;
			contentInfo = new ContentInfo(ContentInfo.DATA_OID, new DerValue(
					DerValue.tag_OctetString, daten));

			X509Certificate[] certificates = { x509 };

			java.math.BigInteger serial = x509.getSerialNumber();

			// SignerInformationen anlegen wer das Cert Signiert hat. 
			SignerInfo si = new SignerInfo(new X500Name(x509.getIssuerDN()
					.getName()), serial,
					AlgorithmId.getAlgorithmId(digestAlgorithm),
					authenticatedAttributes, new AlgorithmId(
							AlgorithmId.RSAEncryption_oid), signedAttributes,
					null);	// hier die Informationen zum Signierer der das die Signierzng durchgeführt hat 

			// Die Inforamtionen wweden dann alls Array apgespeichert und dann an das PKCS7 Konstruktor übergeben.
			// Die Infos werden in einem Array gespeichert um Sie an den PKCS7 Konstruktor zu übergeben.
			SignerInfo[] signerInfos = { si };

			p7 = new PKCS7(digestAlgorithmIds, contentInfo, certificates,
					signerInfos); // hier die Erzegung des Cert.

			p7.encodeSignedData(ausgabe);
			
			// Test ob Verifizierung funktioniert.
			try {
				p7.verify();
			} catch (Exception e) {
				System.out.println("Error en validacion:" + e.getMessage());
				e.printStackTrace();
			}

		} catch (Exception ex) {
			ex.printStackTrace();
			return null;
		}	
			
		

		return ausgabe ; // Rückgabe des PKCS Zerts p7
	}
```


----------



## SlaterB (3. Aug 2011)

nun gut, ein ByteArrayOutputStream geht gerade so noch, da kann man das Ergebnis nämlich abfragen,
caste auf ByteArrayOutputStream, hole das byte[] mit getBytes(), 
die bytes kann man dann ausgeben (mein guter Tipp  ). meinetwegen als Objekt speichern, ist serialisierbar,
oder direkt in eine Binärdatei, in einen FileOutputStream schreiben


----------



## Leno (3. Aug 2011)

Sorry hast du vielleicht einen Quellcode mit dem ich das erreichen kann das Casten geht dann so


```
ByteArrayOutputStream stream = (ByteArrayOutputStream) out;
```

und dann wie kann ich dies dann auf Festplatte überführen ?

also als PKCS7 hast du vielleicht eine idee?


----------



## SlaterB (3. Aug 2011)

ich sagte doch
> hole das byte[] mit getBytes(), 
?
wie man ein byte[] auf eine Festplatte speichert ist nun absoluter Grundkurs Java, in jedem Lehrbuch ausführlich in einem Kapitel behandelt, 
auch sonst überall im Internet zu finden

> also als PKCS7 hast du vielleicht eine idee? 
nicht kompliziert denken, mit PKCS7 hat das erstmal nichts mehr zu tun, falls es keine guten Gründe wie spezielles Dateiformat gibt,
deine Aufgabe heißt jetzt 'byte[] auf Festplatte speichern'


----------



## Nobbs (5. Aug 2011)

Falls dus noch brauchst, so würde ichs af die Festplatte schreiben:


```
FileOutputStream fos= new FileOutputStream("hier deinen gewünschten speicherort angeben");
fos.write(((ByteArrayOutputStream)out).toByteArray());
fos.close();
```

try catch muss natürlich noch außenrum.


----------

