Дублирование кода в блоке catch необходимо из-за нарушения безопасности в функции фильтрации исключений (не предоставляется C #, но Visual Basic и другие предлагают его). Это позволяет злоумышленнику выполнять свой код в вашем блоке try-catch-finally, после того, как перехватится исключение и до выполнения блока finally.
Угроза выглядит следующим образом: пользователь Visual Basic вашей библиотеки вызывает исключение после Unprotect () (даже OutOfMemoryException из-за нехватки памяти), CLR не находит блок catch, затем CLR выполняет код фильтра исключений пользователя, этот код крадет Unprotect () данные, и только после этого CLR выполняет Protect () в блоке finally.
Итак, поместите код очистки безопасности в блоки catch и finally, обычная очистка останется только в конце.