diff --git a/src/conf.c b/src/conf.c
index 1560541a..b7c0179e 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -400,6 +400,70 @@ bool read_connection_config(connection_t *c) {
 	return x;
 }
 
+static void disable_old_keys(const char *filename) {
+	char tmpfile[PATH_MAX] = "";
+	char buf[1024];
+	bool disabled = false;
+	FILE *r, *w;
+
+	r = fopen(filename, "r");
+	if(!r)
+		return;
+
+	snprintf(tmpfile, sizeof tmpfile, "%s.tmp", filename);
+
+	w = fopen(tmpfile, "w");
+
+	while(fgets(buf, sizeof buf, r)) {
+		if(!strncmp(buf, "-----BEGIN RSA", 14)) {	
+			buf[11] = 'O';
+			buf[12] = 'L';
+			buf[13] = 'D';
+			disabled = true;
+		}
+		else if(!strncmp(buf, "-----END RSA", 12)) {	
+			buf[ 9] = 'O';
+			buf[10] = 'L';
+			buf[11] = 'D';
+			disabled = true;
+		}
+		if(w && fputs(buf, w) < 0) {
+			disabled = false;
+			break;
+		}
+	}
+
+	if(w)
+		fclose(w);
+	fclose(r);
+
+	if(!w && disabled) {
+		fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n");
+		return;
+	}
+
+	if(disabled) {
+#ifdef HAVE_MINGW
+		// We cannot atomically replace files on Windows.
+		char bakfile[PATH_MAX] = "";
+		snprintf(bakfile, sizeof bakfile, "%s.bak", filename);
+		if(rename(filename, bakfile) || rename(tmpfile, filename)) {
+			rename(bakfile, filename);
+#else
+		if(rename(tmpfile, filename)) {
+#endif
+			fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n");
+		} else  {
+#ifdef HAVE_MINGW
+			unlink(bakfile);
+#endif
+			fprintf(stderr, "Warning: old key(s) found and disabled.\n");
+		}
+	}
+
+	unlink(tmpfile);
+}
+
 FILE *ask_and_open(const char *filename, const char *what) {
 	FILE *r;
 	char *directory;
@@ -447,9 +511,11 @@ FILE *ask_and_open(const char *filename, const char *what) {
 
 	umask(0077);				/* Disallow everything for group and other */
 
+	disable_old_keys(fn);
+
 	/* Open it first to keep the inode busy */
 
-	r = fopen(fn, "r+") ?: fopen(fn, "w+");
+	r = fopen(fn, "a");
 
 	if(!r) {
 		fprintf(stderr, "Error opening file `%s': %s\n",
@@ -460,42 +526,4 @@ FILE *ask_and_open(const char *filename, const char *what) {
 	return r;
 }
 
-bool disable_old_keys(FILE *f) {
-	char buf[100];
-	long pos;
-	bool disabled = false;
 
-	rewind(f);
-	pos = ftell(f);
-
-	if(pos < 0)
-		return false;
-
-	while(fgets(buf, sizeof buf, f)) {
-		if(!strncmp(buf, "-----BEGIN RSA", 14)) {	
-			buf[11] = 'O';
-			buf[12] = 'L';
-			buf[13] = 'D';
-			if(fseek(f, pos, SEEK_SET))
-				break;
-			if(fputs(buf, f) <= 0)
-				break;
-			disabled = true;
-		}
-		else if(!strncmp(buf, "-----END RSA", 12)) {	
-			buf[ 9] = 'O';
-			buf[10] = 'L';
-			buf[11] = 'D';
-			if(fseek(f, pos, SEEK_SET))
-				break;
-			if(fputs(buf, f) <= 0)
-				break;
-			disabled = true;
-		}
-		pos = ftell(f);
-		if(pos < 0)
-			break;
-	}
-
-	return disabled;
-}
diff --git a/src/conf.h b/src/conf.h
index 5b0796e5..46a42b1d 100644
--- a/src/conf.h
+++ b/src/conf.h
@@ -63,6 +63,5 @@ extern bool read_server_config(void);
 extern bool read_connection_config(struct connection_t *);
 extern FILE *ask_and_open(const char *, const char *);
 extern bool is_safe_path(const char *);
-extern bool disable_old_keys(FILE *);
 
 #endif							/* __TINC_CONF_H__ */
diff --git a/src/tincd.c b/src/tincd.c
index a1be971a..d0b00b0d 100644
--- a/src/tincd.c
+++ b/src/tincd.c
@@ -362,9 +362,6 @@ static bool keygen(int bits) {
 	if(!f)
 		return false;
 
-	if(disable_old_keys(f))
-		fprintf(stderr, "Warning: old key(s) found and disabled.\n");
-  
 #ifdef HAVE_FCHMOD
 	/* Make it unreadable for others. */
 	fchmod(fileno(f), 0600);
@@ -385,9 +382,6 @@ static bool keygen(int bits) {
 	if(!f)
 		return false;
 
-	if(disable_old_keys(f))
-		fprintf(stderr, "Warning: old key(s) found and disabled.\n");
-
 	fputc('\n', f);
 	PEM_write_RSAPublicKey(f, rsa_key);
 	fclose(f);